diff --git a/agents-api/agents_api/activities/logger.py b/agents-api/agents_api/activities/logger.py new file mode 100644 index 000000000..4880d0652 --- /dev/null +++ b/agents-api/agents_api/activities/logger.py @@ -0,0 +1,8 @@ +import logging + + +logger = logging.getLogger(__name__) +h = logging.StreamHandler() +fmt = logging.Formatter("[%(asctime)s/%(levelname)s] - %(message)s") +h.setFormatter(fmt) +logger.addHandler(h) diff --git a/agents-api/agents_api/activities/summarization.py b/agents-api/agents_api/activities/summarization.py index 85a8a9ae5..e44fc455d 100644 --- a/agents-api/agents_api/activities/summarization.py +++ b/agents-api/agents_api/activities/summarization.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 +import asyncio from uuid import UUID from typing import Callable from textwrap import dedent @@ -11,7 +12,10 @@ ) from agents_api.common.protocol.entries import Entry from ..model_registry import JULEP_MODELS -from ..env import summarization_model_name, model_inference_url, model_api_key +from ..env import model_inference_url, model_api_key, summarization_model_name +from agents_api.rec_sum.entities import get_entities +from agents_api.rec_sum.summarize import summarize_messages +from agents_api.rec_sum.trim import trim_messages example_previous_memory = """ @@ -160,28 +164,56 @@ async def run_prompt( @activity.defn async def summarization(session_id: str) -> None: session_id = UUID(session_id) - entries = [ - Entry(**row) - for _, row in get_toplevel_entries_query(session_id=session_id).iterrows() - ] + entries = [] + entities_entry_ids = [] + for _, row in get_toplevel_entries_query(session_id=session_id).iterrows(): + if row["role"] == "system" and row.get("name") == "entities": + entities_entry_ids.append(UUID(row["entry_id"], version=4)) + else: + entries.append(row) assert len(entries) > 0, "no need to summarize on empty entries list" - response = await run_prompt( - dialog=entries, previous_memories=[], model=f"openai/{summarization_model_name}" + summarized, entities = await asyncio.gather( + summarize_messages(entries, model=summarization_model_name), + get_entities(entries, model=summarization_model_name), ) - - new_entry = Entry( + trimmed_messages = await trim_messages(summarized, model=summarization_model_name) + ts_delta = (entries[1]["timestamp"] - entries[0]["timestamp"]) / 2 + new_entities_entry = Entry( session_id=session_id, source="summarizer", role="system", - name="information", - content=response, - timestamp=entries[-1].timestamp + 0.01, + name="entities", + content=entities["content"], + timestamp=entries[0]["timestamp"] + ts_delta, ) entries_summarization_query( session_id=session_id, - new_entry=new_entry, - old_entry_ids=[e.id for e in entries], + new_entry=new_entities_entry, + old_entry_ids=entities_entry_ids, ) + + trimmed_map = { + m["index"]: m["content"] for m in trimmed_messages if m.get("index") is not None + } + + for idx, msg in enumerate(summarized): + new_entry = Entry( + session_id=session_id, + source="summarizer", + role="system", + name="information", + content=trimmed_map.get(idx, msg["content"]), + timestamp=entries[-1]["timestamp"] + 0.01, + ) + + entries_summarization_query( + session_id=session_id, + new_entry=new_entry, + old_entry_ids=[ + UUID(entries[idx - 1]["entry_id"], version=4) + for idx in msg["summarizes"] + ], + ) diff --git a/agents-api/agents_api/activities/truncation.py b/agents-api/agents_api/activities/truncation.py new file mode 100644 index 000000000..cbe0ee730 --- /dev/null +++ b/agents-api/agents_api/activities/truncation.py @@ -0,0 +1,51 @@ +from uuid import UUID +from temporalio import activity +from agents_api.models.entry.entries_summarization import get_toplevel_entries_query +from agents_api.models.entry.delete_entries import delete_entries +from agents_api.autogen.openapi_model import Role +from agents_api.common.protocol.entries import Entry + + +def get_extra_entries(messages: list[Entry], token_count_threshold: int) -> list[UUID]: + if not len(messages): + return messages + + result: list[UUID] = [] + token_cnt, offset = 0, 0 + if messages[0].role == Role.system: + token_cnt, offset = messages[0].token_count, 1 + + for m in reversed(messages[offset:]): + token_cnt += m.token_count + if token_cnt < token_count_threshold: + continue + else: + result.append(m.id) + + return result + + +@activity.defn +async def truncation(session_id: str, token_count_threshold: int) -> None: + session_id = UUID(session_id) + + delete_entries( + get_extra_entries( + [ + Entry( + entry_id=row["entry_id"], + session_id=session_id, + source=row["source"], + role=Role(row["role"]), + name=row["name"], + content=row["content"], + created_at=row["created_at"], + timestamp=row["timestamp"], + ) + for _, row in get_toplevel_entries_query( + session_id=session_id + ).iterrows() + ], + token_count_threshold, + ), + ) diff --git a/agents-api/agents_api/autogen/openapi_model.py b/agents-api/agents_api/autogen/openapi_model.py index 6bba870dd..68d0d0901 100644 --- a/agents-api/agents_api/autogen/openapi_model.py +++ b/agents-api/agents_api/autogen/openapi_model.py @@ -124,6 +124,14 @@ class Session(BaseModel): """ Render system and assistant message content as jinja templates """ + token_budget: int | None = None + """ + Threshold value for the adaptive context functionality + """ + context_overflow: str | None = None + """ + Action to start on context window overflow + """ class CreateSessionRequest(BaseModel): @@ -151,6 +159,14 @@ class CreateSessionRequest(BaseModel): """ Render system and assistant message content as jinja templates """ + token_budget: int | None = None + """ + Threshold value for the adaptive context functionality + """ + context_overflow: str | None = None + """ + Action to start on context window overflow + """ class UpdateSessionRequest(BaseModel): @@ -166,6 +182,14 @@ class UpdateSessionRequest(BaseModel): """ Optional metadata """ + token_budget: int | None = None + """ + Threshold value for the adaptive context functionality + """ + context_overflow: str | None = None + """ + Action to start on context window overflow + """ class UpdateUserRequest(BaseModel): @@ -753,6 +777,14 @@ class PatchSessionRequest(BaseModel): """ Optional metadata """ + token_budget: int | None = None + """ + Threshold value for the adaptive context functionality + """ + context_overflow: str | None = None + """ + Action to start on context window overflow + """ class PartialFunctionDef(BaseModel): diff --git a/agents-api/agents_api/clients/temporal.py b/agents-api/agents_api/clients/temporal.py index e10c97df5..902a75d65 100644 --- a/agents-api/agents_api/clients/temporal.py +++ b/agents-api/agents_api/clients/temporal.py @@ -46,3 +46,16 @@ async def run_embed_docs_task( task_queue="memory-task-queue", id=str(job_id), ) + + +async def run_truncation_task( + token_count_threshold: int, session_id: UUID, job_id: UUID +): + client = await get_client() + + await client.execute_workflow( + "TruncationWorkflow", + args=[str(session_id), token_count_threshold], + task_queue="memory-task-queue", + id=str(job_id), + ) diff --git a/agents-api/agents_api/common/protocol/entries.py b/agents-api/agents_api/common/protocol/entries.py index 25c1bde3c..e6ff945fb 100644 --- a/agents-api/agents_api/common/protocol/entries.py +++ b/agents-api/agents_api/common/protocol/entries.py @@ -7,6 +7,7 @@ Role, ChatMLImageContentPart, ChatMLTextContentPart, + Detail, ) from agents_api.common.utils.datetime import utcnow @@ -14,6 +15,10 @@ Tokenizer = Literal["character_count"] +LOW_IMAGE_TOKEN_COUNT = 85 +HIGH_IMAGE_TOKEN_COUNT = 85 + 4 * 170 + + class Entry(BaseModel): """Represents an entry in the system, encapsulating all necessary details such as ID, session ID, source, role, and content among others.""" @@ -44,12 +49,15 @@ def token_count(self) -> int: elif isinstance(self.content, dict): content_length = len(json.dumps(self.content)) elif isinstance(self.content, list): - text = "" for part in self.content: - # TODO: how to calc token count for images? if isinstance(part, ChatMLTextContentPart): - text += part.text - content_length = len(text) + content_length += len(part.text) + elif isinstance(part, ChatMLImageContentPart): + content_length += ( + LOW_IMAGE_TOKEN_COUNT + if part.image_url.detail == Detail.low + else HIGH_IMAGE_TOKEN_COUNT + ) # Divide the content length by 3.5 to estimate token count based on character count. return int(content_length // 3.5) diff --git a/agents-api/agents_api/common/protocol/sessions.py b/agents-api/agents_api/common/protocol/sessions.py index c9fa81075..683b36aaf 100644 --- a/agents-api/agents_api/common/protocol/sessions.py +++ b/agents-api/agents_api/common/protocol/sessions.py @@ -44,3 +44,5 @@ class SessionData(BaseModel): metadata: Dict = {} user_metadata: Optional[Dict] = None agent_metadata: Dict = {} + token_budget: int | None = None + context_overflow: str | None = None diff --git a/agents-api/agents_api/common/utils/messages.py b/agents-api/agents_api/common/utils/messages.py index c59d751c0..14fe817cc 100644 --- a/agents-api/agents_api/common/utils/messages.py +++ b/agents-api/agents_api/common/utils/messages.py @@ -1,4 +1,5 @@ import json +from typing import cast from agents_api.autogen.openapi_model import ( ChatMLTextContentPart, ChatMLImageContentPart, @@ -23,3 +24,17 @@ def content_to_json( result = [{"type": "text", "text": json.dumps(content, indent=4)}] return result + + +def stringify_content( + msg: str | list[ChatMLTextContentPart] | list[ChatMLImageContentPart] | dict, +) -> str: + content = "" + if isinstance(msg, list): + content = " ".join([part.text for part in msg if part.type == "text"]) + elif isinstance(msg, str): + content = msg + elif isinstance(msg, dict) and msg["type"] == "text": + content = cast(str, msg["text"]) + + return content diff --git a/agents-api/agents_api/env.py b/agents-api/agents_api/env.py index b4524004c..2825aba27 100644 --- a/agents-api/agents_api/env.py +++ b/agents-api/agents_api/env.py @@ -26,12 +26,6 @@ model_api_key: str = env.str("MODEL_API_KEY", default=None) model_inference_url: str = env.str("MODEL_INFERENCE_URL", default=None) openai_api_key: str = env.str("OPENAI_API_KEY", default="") -summarization_ratio_threshold: float = env.float( - "MAX_TOKENS_RATIO_TO_SUMMARIZE", default=0.5 -) -summarization_tokens_threshold: int = env.int( - "SUMMARIZATION_TOKENS_THRESHOLD", default=2048 -) summarization_model_name: str = env.str( "SUMMARIZATION_MODEL_NAME", default="gpt-4-turbo" ) @@ -78,8 +72,6 @@ debug=debug, cozo_host=cozo_host, cozo_auth=cozo_auth, - summarization_ratio_threshold=summarization_ratio_threshold, - summarization_tokens_threshold=summarization_tokens_threshold, worker_url=worker_url, sentry_dsn=sentry_dsn, temporal_endpoint=temporal_endpoint, diff --git a/agents-api/agents_api/models/entry/delete_entries.py b/agents-api/agents_api/models/entry/delete_entries.py index 2affa321d..7bdb2dce7 100644 --- a/agents-api/agents_api/models/entry/delete_entries.py +++ b/agents-api/agents_api/models/entry/delete_entries.py @@ -61,3 +61,55 @@ def delete_entries_query(session_id: UUID) -> tuple[str, dict]: }""" return (query, {"session_id": str(session_id)}) + + +@cozo_query +def delete_entries(entry_ids: list[UUID]) -> tuple[str, dict]: + query = """ + { + input[entry_id_str] <- $entry_ids + + ?[ + entry_id, + session_id, + source, + role, + name, + content, + token_count, + tokenizer, + created_at, + timestamp, + ] := + input[entry_id_str], + entry_id = to_uuid(entry_id_str), + *entries { + entry_id, + session_id, + source, + role, + name, + content, + token_count, + tokenizer, + created_at, + timestamp, + } + + :delete entries { + entry_id, + session_id, + source, + role, + name, + content, + token_count, + tokenizer, + created_at, + timestamp, + } + + :returning + }""" + + return (query, {"entry_ids": [[str(id)] for id in entry_ids]}) diff --git a/agents-api/agents_api/models/session/create_session.py b/agents-api/agents_api/models/session/create_session.py index 6cf149bce..8eebd5280 100644 --- a/agents-api/agents_api/models/session/create_session.py +++ b/agents-api/agents_api/models/session/create_session.py @@ -21,6 +21,8 @@ def create_session_query( situation: str | None, metadata: dict = {}, render_templates: bool = False, + token_budget: int | None = None, + context_overflow: str | None = None, ) -> tuple[str, dict]: """ Constructs and executes a datalog query to create a new session in the database. @@ -33,6 +35,8 @@ def create_session_query( - situation (str | None): The situation/context of the session. - metadata (dict): Additional metadata for the session. - render_templates (bool): Specifies whether to render templates. + - token_budget (int | None): Token count threshold to consider it as a context window overflow + - context_overflow (str | None): Action to take on context window overflow Returns: - pd.DataFrame: The result of the query execution. @@ -57,12 +61,14 @@ def create_session_query( } } { # Insert the new session data into the 'session' table with the specified columns. - ?[session_id, developer_id, situation, metadata, render_templates] <- [[ + ?[session_id, developer_id, situation, metadata, render_templates, token_budget, context_overflow] <- [[ $session_id, $developer_id, $situation, $metadata, $render_templates, + $token_budget, + $context_overflow, ]] :insert sessions { @@ -71,6 +77,8 @@ def create_session_query( situation, metadata, render_templates, + token_budget, + context_overflow, } # Specify the data to return after the query execution, typically the newly created session's ID. :returning @@ -87,5 +95,7 @@ def create_session_query( "situation": situation, "metadata": metadata, "render_templates": render_templates, + "token_budget": token_budget, + "context_overflow": context_overflow, }, ) diff --git a/agents-api/agents_api/models/session/get_session.py b/agents-api/agents_api/models/session/get_session.py index a47c09495..09b763489 100644 --- a/agents-api/agents_api/models/session/get_session.py +++ b/agents-api/agents_api/models/session/get_session.py @@ -44,6 +44,8 @@ def get_session_query( created_at, metadata, render_templates, + token_budget, + context_overflow, ] := input[developer_id, id], *sessions{ developer_id, @@ -54,6 +56,8 @@ def get_session_query( updated_at: validity, metadata, render_templates, + token_budget, + context_overflow, @ "NOW" }, *session_lookup{ diff --git a/agents-api/agents_api/models/session/list_sessions.py b/agents-api/agents_api/models/session/list_sessions.py index e0cf4a59e..ec5c40310 100644 --- a/agents-api/agents_api/models/session/list_sessions.py +++ b/agents-api/agents_api/models/session/list_sessions.py @@ -50,6 +50,8 @@ def list_sessions_query( updated_at, created_at, metadata, + token_budget, + context_overflow, ] := input[developer_id], *sessions{{ @@ -60,6 +62,8 @@ def list_sessions_query( created_at, updated_at: validity, metadata, + token_budget, + context_overflow, @ "NOW" }}, *session_lookup{{ diff --git a/agents-api/agents_api/models/session/session_data.py b/agents-api/agents_api/models/session/session_data.py index d3a5bafc3..5d2c13996 100644 --- a/agents-api/agents_api/models/session/session_data.py +++ b/agents-api/agents_api/models/session/session_data.py @@ -47,6 +47,8 @@ def session_data_query( default_settings, metadata, render_templates, + token_budget, + context_overflow, user_metadata, agent_metadata, ] := input[developer_id, session_id], @@ -59,6 +61,8 @@ def session_data_query( updated_at: validity, metadata, render_templates, + token_budget, + context_overflow, @ "NOW" }, *session_lookup{ @@ -116,6 +120,8 @@ def session_data_query( default_settings, metadata, render_templates, + token_budget, + context_overflow, user_metadata, agent_metadata, ] := input[developer_id, session_id], @@ -128,6 +134,8 @@ def session_data_query( updated_at: validity, metadata, render_templates, + token_budget, + context_overflow, @ "NOW" }, *session_lookup{ diff --git a/agents-api/agents_api/models/utils.py b/agents-api/agents_api/models/utils.py index a6fb71c86..fe269b17c 100644 --- a/agents-api/agents_api/models/utils.py +++ b/agents-api/agents_api/models/utils.py @@ -1,12 +1,15 @@ from functools import wraps -from typing import Callable +from typing import Callable, ParamSpec import pandas as pd from ..clients.cozo import client as cozo_client -def cozo_query(func: Callable[..., tuple[str, dict]]): +P = ParamSpec("P") + + +def cozo_query(func: Callable[P, tuple[str, dict]]): """ Decorator that wraps a function that takes arbitrary arguments, and returns a (query string, variables) tuple. diff --git a/agents-api/agents_api/rec_sum/__init__.py b/agents-api/agents_api/rec_sum/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/agents-api/agents_api/rec_sum/data.py b/agents-api/agents_api/rec_sum/data.py new file mode 100644 index 000000000..93e78851c --- /dev/null +++ b/agents-api/agents_api/rec_sum/data.py @@ -0,0 +1,25 @@ +import json +from pathlib import Path + + +module_directory = Path(__file__).parent + + +with open(f"{module_directory}/entities_example_chat.json", "r") as _f: + entities_example_chat = json.load(_f) + + +with open(f"{module_directory}/trim_example_chat.json", "r") as _f: + trim_example_chat = json.load(_f) + + +with open(f"{module_directory}/trim_example_result.json", "r") as _f: + trim_example_result = json.load(_f) + + +with open(f"{module_directory}/summarize_example_chat.json", "r") as _f: + summarize_example_chat = json.load(_f) + + +with open(f"{module_directory}/summarize_example_result.json", "r") as _f: + summarize_example_result = json.load(_f) diff --git a/agents-api/agents_api/rec_sum/entities.py b/agents-api/agents_api/rec_sum/entities.py new file mode 100644 index 000000000..db6cba826 --- /dev/null +++ b/agents-api/agents_api/rec_sum/entities.py @@ -0,0 +1,89 @@ +import json +import pandas as pd + +from typing import Any +from tenacity import retry, stop_after_attempt + +from .data import entities_example_chat +from .generate import generate +from .utils import chatml, get_names_from_session + + +############## +## Entities ## +############## + +entities_example_plan = """\ +Thinking step by step: +- To add context for future entries, let's outline the main entities in the session above. +- In this session, as mentioned in the first message metadata, the user's name is Camille and the assistant's name is JaneBot. +- They talk about Elon Musk and the banana tattoo on Camille's arm briefly.""" + + +entities_example_result = """\ +1. Camille (The user): Humorous, creative, and enjoys playful banter. +2. JaneBot (The assistant): Engages in lighthearted conversation and tries to guess user's thoughts. +3. Elon Musk: Camille and JaneBot discuss the polarizing tech and space industry figure. +4. Banana Tattoo: Camille has a tattoo of a banana on their arm.""" + + +entities_instructions = """\ +Your goal is to identify the main entities in the session. Entities should include: +- Characters in the conversation: Assistant, User1, User2 +- People references or spoken about +- Objects discussed about +- Places of interest +- ...etc + +Instructions: +- Identify and extract important entities discussed. +- You can add entities that, while not directly mentioned, are important in the context of the conversation. +- Write a brief line to provide context about each entity explaining it's relevance to the conversation. +- Enclose your answer inside XML tags. +- See the example to get a better idea of the task.""" + + +def make_entities_prompt( + session: list[pd.Series] | list[Any], user="a user", assistant="gpt-4-turbo", **_ +): + session = [m.to_dict() if isinstance(m, pd.Series) else m for m in session] + session_json_str = json.dumps(session, indent=2) + + return [ + f"You are given a session history of a chat between {user or 'a user'} and {assistant or 'gpt-4-turbo'}. The session is formatted in the ChatML JSON format (from OpenAI).\n\n{entities_instructions}\n\n\n{json.dumps(entities_example_chat, indent=2)}\n\n\n\n{entities_example_plan}\n\n\n\n{entities_example_result}\n", + f"Begin! Write the entities as a Markdown formatted list. First write your plan inside and then the extracted entities between .\n\n\n{session_json_str}\n\n", + ] + + +@retry(stop=stop_after_attempt(2)) +async def get_entities( + chat_session, + model="gpt-4-turbo", + stop=["= 2, "Session is too short" + + names = get_names_from_session(chat_session) + system_prompt, user_message = make_entities_prompt(chat_session, **names) + messages = [chatml.system(system_prompt), chatml.user(user_message)] + result = await generate( + messages, + model=model, + stop=stop, + temperature=temperature, + **kwargs, + ) + + assert "" in result["content"] + result["content"] = ( + result["content"] + .split("")[-1] + .replace("", "") + .strip() + ) + result["role"] = "system" + result["name"] = "entities" + + return chatml.make(**result) diff --git a/agents-api/agents_api/rec_sum/entities_example_chat.json b/agents-api/agents_api/rec_sum/entities_example_chat.json new file mode 100644 index 000000000..32d994877 --- /dev/null +++ b/agents-api/agents_api/rec_sum/entities_example_chat.json @@ -0,0 +1,68 @@ +[ + { + "role": "system", + "content": "just have a casual chat with a friend friend" + }, + { + "role": "user", + "name": "Camille", + "content": "yo" + }, + { + "role": "assistant", + "name": "JaneBot", + "content": "Hey, how's it going?" + }, + { + "role": "user", + "content": "what you think about elon?" + }, + { + "role": "assistant", + "content": "Elon Musk is definitely a fascinating and polarizing figure. He's accomplished a lot in the tech and space industries with companies like Tesla and SpaceX. What do you think about him?" + }, + { + "role": "user", + "content": "very polarizing, dude is nuts but in a fun way" + }, + { + "role": "assistant", + "content": "Haha, yeah, that's a pretty accurate description of him. He definitely knows how to keep things interesting and push boundaries. It's always exciting to see what he'll come up with next." + }, + { + "role": "user", + "content": "i am glad he exists" + }, + { + "role": "assistant", + "content": "For sure, he's definitely made a huge impact on various industries. It's always interesting to see how his projects and ideas continue to evolve." + }, + { + "role": "user", + "content": "what are your thoughts on bananas?" + }, + { + "role": "assistant", + "content": "I actually love bananas! They're a great snack, full of nutrients and easy to eat on the go. How about you, do you like bananas?" + }, + { + "role": "user", + "content": "super much. i have a tattoo of a banana on my arm" + }, + { + "role": "assistant", + "content": "That's awesome! A banana tattoo sounds like a fun and unique choice. It must be a great conversation starter." + }, + { + "role": "user", + "content": "anyway what number am I thinking of?" + }, + { + "role": "assistant", + "content": "Hmm, I'll take a wild guess and say you're thinking of the number 7. Did I get it right?" + }, + { + "role": "user", + "content": "no" + } +] \ No newline at end of file diff --git a/agents-api/agents_api/rec_sum/generate.py b/agents-api/agents_api/rec_sum/generate.py new file mode 100644 index 000000000..e05111faa --- /dev/null +++ b/agents-api/agents_api/rec_sum/generate.py @@ -0,0 +1,25 @@ +from tenacity import retry, stop_after_attempt, wait_fixed +from agents_api.env import model_inference_url, model_api_key +from agents_api.model_registry import JULEP_MODELS +from litellm import acompletion + + +@retry(wait=wait_fixed(2), stop=stop_after_attempt(5)) +async def generate( + messages: list[dict], + model: str = "gpt-4-turbo", + **kwargs, +) -> dict: + base_url, api_key = None, None + if model in JULEP_MODELS: + base_url, api_key = model_inference_url, model_api_key + model = f"openai/{model}" + + result = await acompletion( + model=model, + messages=messages, + base_url=base_url, + api_key=api_key, + ) + + return result.choices[0].message.json() diff --git a/agents-api/agents_api/rec_sum/summarize.py b/agents-api/agents_api/rec_sum/summarize.py new file mode 100644 index 000000000..4ae546e8b --- /dev/null +++ b/agents-api/agents_api/rec_sum/summarize.py @@ -0,0 +1,94 @@ +import json + +from tenacity import retry, stop_after_attempt + +from .data import summarize_example_chat, summarize_example_result +from .generate import generate +from .utils import chatml, add_indices, get_names_from_session + + +########## +## summarize ## +########## + +summarize_example_plan = """\ +Planning step by step: +- We can replace entries 1,2,3,4 with a summary of those messages. +- We can replace entries 5,6,7,8 similarly. +- It could be disruptive to remove messages 9-16 because that might lose the joke's context. +- We can safely summarize entries 17,18 without losing context. +- We should keep 21 because it's given by the user and they might ask about it again. +- We should keep the assistant's response in message 22 to keep the context. +- Messages 23-32 are repetitive and can be summarized. +- We should retain message 33 since it's a direct request from the user. +- We can safely summarize message 34's essay into just the salient points only.""" + + +summarize_instructions = """\ +Your goal is to compactify the history by coalescing redundant information in messages into their summary in order to reduce its size and save costs. + +Instructions: +- Combine multiple messages into summaries when possible as long as that doesn't disrupt the structure of the session. +- You can convert large messages (such as an essay) into a list of points. +- Do not summarize content that the user shared since it might be relevant to future messages. +- Make sure to preserve the tone of the conversation and its flow. Refer to the example and do EXACTLY as shown. +- VERY IMPORTANT: Add the indices of messages that are being summarized so that those messages can then be removed from the session otherwise, there'll be no way to identify which messages to remove. See example for more details.""" + + +def make_summarize_prompt(session, user="a user", assistant="gpt-4-turbo", **_): + return [ + f"You are given a session history of a chat between {user or 'a user'} and {assistant or 'gpt-4-turbo'}. The session is formatted in the ChatML JSON format (from OpenAI).\n\n{summarize_instructions}\n\n\n{json.dumps(add_indices(summarize_example_chat), indent=2)}\n\n\n\n{summarize_example_plan}\n\n\n\n{json.dumps(summarize_example_result, indent=2)}\n", + f"Begin! Write the summarized messages as a json list just like the example above. First write your plan inside and then your answer between . Don't forget to add the indices of the messages being summarized alongside each summary.\n\n\n{json.dumps(add_indices(session), indent=2)}\n\n", + ] + + +@retry(stop=stop_after_attempt(2)) +async def summarize_messages( + chat_session, + model="gpt-4-turbo", + stop=["= 2, "Session is too short" + + offset = 0 + + # Remove the system prompt if present + if ( + chat_session[0]["role"] == "system" + and chat_session[0].get("name") != "entities" + ): + chat_session = chat_session[1:] + + # The indices are not matched up correctly + offset = 1 + + names = get_names_from_session(chat_session) + system_prompt, user_message = make_summarize_prompt(chat_session, **names) + messages = [chatml.system(system_prompt), chatml.user(user_message)] + result = await generate( + messages, + model=model, + stop=stop, + temperature=temperature, + **kwargs, + ) + + assert "" in result["content"] + summarized_messages = json.loads( + result["content"] + .split("")[-1] + .replace("", "") + .strip() + ) + + assert all((msg.get("summarizes") is not None for msg in summarized_messages)) + + # Correct offset + summarized_messages = [ + {**msg, "summarizes": [i + offset for i in msg["summarizes"]]} + for msg in summarized_messages + ] + + return summarized_messages diff --git a/agents-api/agents_api/rec_sum/summarize_example_chat.json b/agents-api/agents_api/rec_sum/summarize_example_chat.json new file mode 100644 index 000000000..f7897cc36 --- /dev/null +++ b/agents-api/agents_api/rec_sum/summarize_example_chat.json @@ -0,0 +1,144 @@ +[ + { + "role": "system", + "content": "just have a casual chat with a friend friend" + }, + { + "role": "user", + "content": "yo", + "name": "Camille" + }, + { + "role": "assistant", + "content": "Hey, how's it going?", + "name": "JaneBot" + }, + { + "role": "user", + "content": "sup" + }, + { + "role": "assistant", + "content": "Not much, just working and trying to stay busy. How about you?" + }, + { + "role": "user", + "content": "what you think about elon?" + }, + { + "role": "assistant", + "content": "Elon Musk is definitely a fascinating and polarizing figure. He's accomplished a lot in the tech and space industries with companies like Tesla and SpaceX. What do you think about him?" + }, + { + "role": "user", + "content": "very polarizing, dude is nuts but in a fun way" + }, + { + "role": "assistant", + "content": "Haha, yeah, that's a pretty accurate description of him. He definitely knows how to keep things interesting and push boundaries. It's always exciting to see what he'll come up with next." + }, + { + "role": "user", + "content": "i am glad he exists" + }, + { + "role": "assistant", + "content": "For sure, he's definitely made a huge impact on various industries. It's always interesting to see how his projects and ideas continue to evolve." + }, + { + "role": "user", + "content": "what are your thoughts on bananas?" + }, + { + "role": "assistant", + "content": "I actually love bananas! They're a great snack, full of nutrients and easy to eat on the go. How about you, do you like bananas?" + }, + { + "role": "user", + "content": "super much. i have a tattoo of a banana on my arm" + }, + { + "role": "assistant", + "content": "That's awesome! A banana tattoo sounds like a fun and unique choice. It must be a great conversation starter. Do you have any other food-related tattoos?" + }, + { + "role": "user", + "content": "yeah, your mom" + }, + { + "role": "assistant", + "content": "Haha, good one! You got me there. Feel free to keep the jokes coming." + }, + { + "role": "user", + "content": "lulz, u funny" + }, + { + "role": "assistant", + "content": "Glad I could make you laugh! It's always great to share a joke or two. Anything else on your mind, or are we just going with the flow of the conversation?" + }, + { + "role": "user", + "content": "ok if I give you a long story, can you guess its title?" + }, + { + "role": "assistant", + "content": "Sure, I can give it a try! Go ahead and tell me your story, and I'll see if I can guess the title." + }, + { + "role": "user", + "content": "Zero is a beautiful number. Not because it is round and cute (that could be an argument for it nevertheless) but because what it signifies. It marks the beginning of something. It marks the lowest something, or someone can go. It is the ultimate foundation to build anything upon. Over last several years, I’ve started several things from scratch and have failed at many (thus going back to zero), and I’ve realized there’s nothing more liberating than being at zero because the only way from zero is upwards. A very good friend once told me, “Don’t worry if you’ve failed. Rockets that touch the sky always launch from the ground.” As J K Rowling, one of my favorite authors says, “Rock bottom became the solid foundation on which I rebuilt my life.” While zero is liberating, thrilling and exciting, it sometimes also is daunting and overwhelming. Sometimes, I have found myself afraid to do something because I was comfortable being at zero and the task to go from zero to one seemed unnerving. This challenge of writing twenty-six stories was one such adventure. I remember it was the first of April when I decided to pen down a story for each letter of the alphabet. I was afraid if I was unknowingly planning to fool myself on April 1st. I had no clue what to write even for the first letter of the alphabet. I was afraid I’d ruin twenty-six stories if I begin writing them just for the sake of writing. What gave me the courage to take up the challenge was to lower the expectations that I’d have from these stories. My purpose was not to write twenty-six bestseller stories. Mine was to make it a habit of writing every day. Some days everything that came out of my pen was garbage, and on a few days, I loved what my hands typed on the blank paper. And today, with this last story, I am back at zero — a solid foundation for the next adventure. Writing has become my daily habit, and I can remember to write even without my calendar sending me a reminder. I am curious what could I make out of this habit. Shall I start another writing adventure? Will it be a similar series? Will be a novel (long due now)? Or something different altogether? Whatever it’d be, I guess I’ll be little less nervous to begin whatever comes next. I am at zero again, and the only way to go from here is upwards. Realizing that there’ll be one less thing in my daily routine, I feel a particular kind of guilt. It’s the kind of guilt that you feel when you have an ice-cream without telling your younger sibling about it. You kind of like it that you had the ice-cream but also feel guilty for hiding it from them. On the new adventure, whatever it’d be, it’s time to buy an ice-cream for them this time." + }, + { + "role": "assistant", + "content": "Based on the themes of starting anew, embracing failure, and the journey from zero to one, I would guess that the title of this story is \"Back to One.\" It seems to capture the essence of the protagonist's experience and mindset throughout the story. How did I do?" + }, + { + "role": "user", + "content": "ok that's cool but you are wrong. anyway what number am I thinking of?" + }, + { + "role": "assistant", + "content": "Hmm, I'll take a wild guess and say you're thinking of the number 7. Did I get it right?" + }, + { + "role": "user", + "content": "no" + }, + { + "role": "assistant", + "content": "Alright, I'll give it another shot. How about the number 3?" + }, + { + "role": "user", + "content": "no" + }, + { + "role": "assistant", + "content": "I'll try one more time - is the number you're thinking of 9?" + }, + { + "role": "user", + "content": "no" + }, + { + "role": "assistant", + "content": "Looks like I haven't quite nailed it yet! Do you mind sharing which number you had in mind?" + }, + { + "role": "user", + "content": "no" + }, + { + "role": "assistant", + "content": "Fair enough, keeping that mystery alive! If you ever feel like sharing, just let me know. Anything else on your mind or any other games you'd like to play?" + }, + { + "role": "user", + "content": "yes, write an essay about me from your experience with me so far" + }, + { + "role": "assistant", + "content": "From my interactions with you so far, I can tell that you have a great sense of humor and enjoy playful banter. You seem open to random and fun conversations, and you're not afraid to keep things interesting with unexpected twists and turns.\n\nYour creativity shines through in the way you approach different topics, and you have a knack for surprising me with your responses. You're also quite adept at changing the direction of the conversation while maintaining a light and friendly tone.\n\nOverall, chatting with you has been enjoyable and entertaining, and I appreciate the lighthearted and casual vibe you bring to our interactions. I look forward to more fun conversations with you in the future!" + } +] \ No newline at end of file diff --git a/agents-api/agents_api/rec_sum/summarize_example_result.json b/agents-api/agents_api/rec_sum/summarize_example_result.json new file mode 100644 index 000000000..a3a361546 --- /dev/null +++ b/agents-api/agents_api/rec_sum/summarize_example_result.json @@ -0,0 +1,58 @@ +[ + { + "role": "system", + "name": "summary", + "content": "Event: Camille says hi to JaneBot and they reply that they are working and trying to stay busy.", + "summarizes": [ + 1, + 2, + 3, + 4 + ] + }, + { + "role": "system", + "name": "summary", + "content": "Event: They discuss Elon Musk and agree that he can be a polarizing personality.", + "summarizes": [ + 5, + 6, + 7, + 8 + ] + }, + { + "role": "system", + "name": "summary", + "content": "Event: Camille appreciates JaneBot's sense of humor.", + "summarizes": [ + 17, + 18 + ] + }, + { + "role": "system", + "name": "summary", + "content": "Event: Camille asks JaneBot to play \"What number I am thinking of?\" game but she keeps saying \"no\" to all guesses which JaneBot finds really funny.", + "summarizes": [ + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32 + ] + }, + { + "role": "system", + "name": "summary", + "content": "Event: JaneBot wrote an essay about Camille. Summary of the essay:\n1. You have a great sense of humor and enjoy playful, lighthearted banter in conversations.\n2. Your creativity is evident in how you approach topics in unexpected ways and keep conversations interesting.\n3. Chatting with you is enjoyable due to the casual, friendly tone you bring to interactions.", + "summarizes": [ + 34 + ] + } +] \ No newline at end of file diff --git a/agents-api/agents_api/rec_sum/trim.py b/agents-api/agents_api/rec_sum/trim.py new file mode 100644 index 000000000..ef8ae4b73 --- /dev/null +++ b/agents-api/agents_api/rec_sum/trim.py @@ -0,0 +1,74 @@ +import json + +from tenacity import retry, stop_after_attempt + +from .data import trim_example_chat, trim_example_result +from .generate import generate +from .utils import chatml, add_indices, get_names_from_session + + +########## +## Trim ## +########## + +trim_example_plan = """\ +Thinking step by step: +- To trim the context, let's examine the messages in the session above. +- Messages 1, 2, and 3 are succinct and do not need trimming. +- However, messages 4, 5, and 6 are all rather verbose and can be safely trimmed. +- Message 7 is short enough and doesn't need any edits.""" + + +trim_instructions = """\ +Your goal is to identify messages in the session that are needlessly verbose and then trim them in length without losing any meaning or changing the tone of the message. + +Instructions: +- Identify messages that are long and repetitive. +- Longer messages need to be converted into smaller, more compact version of them. +- Make sure to only trim out content that is not important to the context. +- Write down the trimmed messages as a json list along with their indices. +- Enclose your answer inside XML tags. +- See the example to get a better idea of the task.""" + +# It is important to make keep the tone, setting and flow of the conversation consistent while trimming the messages. + + +def make_trim_prompt(session, user="a user", assistant="gpt-4-turbo", **_): + return [ + f"You are given a session history of a chat between {user or 'a user'} and {assistant or 'gpt-4-turbo'}. The session is formatted in the ChatML JSON format (from OpenAI).\n\n{trim_instructions}\n\n\n{json.dumps(add_indices(trim_example_chat), indent=2)}\n\n\n\n{trim_example_plan}\n\n\n\n{json.dumps(trim_example_result, indent=2)}\n", + f"Begin! Write the trimmed messages as a json list. First write your plan inside and then your answer between .\n\n\n{json.dumps(add_indices(session), indent=2)}\n\n", + ] + + +@retry(stop=stop_after_attempt(2)) +async def trim_messages( + chat_session, + model="gpt-4-turbo", + stop=["= 2, "Session is too short" + + names = get_names_from_session(chat_session) + system_prompt, user_message = make_trim_prompt(chat_session, **names) + messages = [chatml.system(system_prompt), chatml.user(user_message)] + result = await generate( + messages, + model=model, + stop=stop, + temperature=temperature, + **kwargs, + ) + + assert "" in result["content"] + trimmed_messages = json.loads( + result["content"].split("")[-1].replace("", "").strip() + ) + + assert all((msg.get("index") is not None for msg in trimmed_messages)) + + # Correct offset + trimmed_messages = [{**msg, "index": msg["index"]} for msg in trimmed_messages] + + return trimmed_messages diff --git a/agents-api/agents_api/rec_sum/trim_example_chat.json b/agents-api/agents_api/rec_sum/trim_example_chat.json new file mode 100644 index 000000000..63d51586e --- /dev/null +++ b/agents-api/agents_api/rec_sum/trim_example_chat.json @@ -0,0 +1,34 @@ +[ + { + "role": "system", + "content": "You are a Large Language Model" + }, + { + "role": "user", + "content": "hi" + }, + { + "role": "assistant", + "content": "Hello! How can I assist you today?" + }, + { + "role": "user", + "content": "I wanted to discuss consciousness with you" + }, + { + "role": "assistant", + "content": "Absolutely, I'd be glad to discuss consciousness with you! It's a fascinating and very complex topic. Consciousness involves awareness of one's internal and external environments, personal thoughts, feelings, and experiences. It's often discussed in various contexts, including philosophy, psychology, and neuroscience. What specific aspects of consciousness are you interested in exploring?" + }, + { + "role": "user", + "content": "well, I am an AGI researcher and I think about consciousness a lot. The most interesting part of it is actually the potential that possibly I am currently talking to a proto-conscious system (you) since we do not really have a concrete definition of consciousness anyway yet. What do you think?" + }, + { + "role": "assistant", + "content": "That's a compelling aspect of the discussion around artificial intelligence. The idea of whether AI, like myself, can possess consciousness, or something akin to it, is a topic of debate among philosophers, computer scientists, and cognitive scientists.\n\nAs it stands, AI, including this system, operates without consciousness. AI systems process data and generate responses based on patterns and instructions in their programming, but they do not experience awareness or subjective experiences. Although AI can simulate aspects of human conversation and behavior, these actions are not accompanied by personal consciousness or an internal life.\n\nThat said, discussions about the potential for artificial general intelligence (AGI) to exhibit features similar to consciousness are ongoing and raise questions about what consciousness fundamentally is, how it can be recognized, and whether it can exist independently of the biological processes that underpin human consciousness.\n\nWhat are your thoughts on the matter, both personally and as an AGI researcher?" + }, + { + "role": "user", + "content": "I am working on Julep AI -- an \"AGI infrastructure lab\" and we are trying to contribute to this space." + } +] \ No newline at end of file diff --git a/agents-api/agents_api/rec_sum/trim_example_result.json b/agents-api/agents_api/rec_sum/trim_example_result.json new file mode 100644 index 000000000..85ef9e997 --- /dev/null +++ b/agents-api/agents_api/rec_sum/trim_example_result.json @@ -0,0 +1,17 @@ +[ + { + "index": 4, + "role": "assistant", + "content": "I'd be glad to discuss consciousness with you! Consciousness involves awareness of one's internal and external environments, thoughts, feelings, and experiences. It's discussed in philosophy, psychology, and neuroscience. What aspects are you interested in?" + }, + { + "index": 5, + "role": "user", + "content": "well, I am an AGI researcher and I think about consciousness. The interesting part is that I may be talking to a proto-conscious system (you) since we do not have a concrete definition of consciousness yet. What do you think?" + }, + { + "index": 6, + "role": "assistant", + "content": "The idea of whether AI, like myself, can possess consciousness, is a topic of debate among scientists.\n\nAI systems process data and generate responses based on patterns in their programming, but they do not experience awareness. Although AI can simulate human conversation and behavior, they are not accompanied by consciousness.\n\nThat said, discussions about AGI to exhibit consciousness are ongoing and raise questions about what consciousness is, how it can be recognized, and whether it can exist independently of the biological processes that underpin human consciousness.\n\nWhat are your thoughts, both personally and as an AGI researcher?" + } +] \ No newline at end of file diff --git a/agents-api/agents_api/rec_sum/utils.py b/agents-api/agents_api/rec_sum/utils.py new file mode 100644 index 000000000..596174e08 --- /dev/null +++ b/agents-api/agents_api/rec_sum/utils.py @@ -0,0 +1,54 @@ +########### +## Utils ## +########### + + +class chatml: + @staticmethod + def make(content, role="system", name=None, **_): + return { + key: value + for key, value in dict(role=role, name=name, content=content).items() + if value is not None + } + + @staticmethod + def user(content, name=None): + return chatml.make(role="user", content=content, name=name) + + @staticmethod + def assistant(content, name=None): + return chatml.make(role="assistant", content=content, name=name) + + @staticmethod + def system(content, name=None): + return chatml.make(content, name=name) + + @staticmethod + def thought(content, name=None): + return chatml.make(content, name="thought") + + @staticmethod + def information(content): + return chatml.system(content, name="information") + + @staticmethod + def summary(content): + return chatml.system(content, name="summary") + + @staticmethod + def entities(content): + return chatml.system(content, name="entity") + + +def add_indices(list_of_dicts, idx_name="index"): + return [{idx_name: i, **msg} for i, msg in enumerate(list_of_dicts)] + + +def get_names_from_session(session): + return { + role: next( + (msg.get("name", None) for msg in session if msg["role"] == role), None + ) + for role in {"user", "assistant", "system"} + } diff --git a/agents-api/agents_api/routers/sessions/protocol.py b/agents-api/agents_api/routers/sessions/protocol.py index d630762db..2350afeb3 100644 --- a/agents-api/agents_api/routers/sessions/protocol.py +++ b/agents-api/agents_api/routers/sessions/protocol.py @@ -23,6 +23,8 @@ class Settings(BaseModel): min_p: float | None = Field(default=0.01) preset: Preset | None = Field(default=None) tools: list[Tool] | None = Field(default=None) + token_budget: int | None = Field(default=None) + context_overflow: str | None = Field(default=None) @field_validator("max_tokens") def set_max_tokens(cls, max_tokens): diff --git a/agents-api/agents_api/routers/sessions/routers.py b/agents-api/agents_api/routers/sessions/routers.py index caa9fcefc..ad87d3aaa 100644 --- a/agents-api/agents_api/routers/sessions/routers.py +++ b/agents-api/agents_api/routers/sessions/routers.py @@ -90,6 +90,8 @@ async def create_session( situation=request.situation, metadata=request.metadata or {}, render_templates=request.render_templates or False, + token_budget=request.token_budget, + context_overflow=request.context_overflow, ) return ResourceCreatedResponse( @@ -151,6 +153,8 @@ async def update_session( developer_id=x_developer_id, situation=request.situation, metadata=request.metadata, + token_budget=request.token_budget, + context_overflow=request.context_overflow, ) return ResourceUpdatedResponse( @@ -182,6 +186,8 @@ async def patch_session( developer_id=x_developer_id, situation=request.situation, metadata=request.metadata, + token_budget=request.token_budget, + context_overflow=request.context_overflow, ) return ResourceUpdatedResponse( diff --git a/agents-api/agents_api/routers/sessions/session.py b/agents-api/agents_api/routers/sessions/session.py index a743f4bf6..da9121366 100644 --- a/agents-api/agents_api/routers/sessions/session.py +++ b/agents-api/agents_api/routers/sessions/session.py @@ -2,8 +2,9 @@ import xxhash from functools import reduce from json import JSONDecodeError -from typing import Callable, cast +from typing import Callable from uuid import uuid4 +from functools import partial from dataclasses import dataclass from openai.types.chat.chat_completion import ChatCompletion @@ -15,14 +16,15 @@ from ...autogen.openapi_model import InputChatMLMessage, Tool, DocIds from ...clients.embed import embed from ...clients.temporal import run_summarization_task +from ...clients.temporal import run_truncation_task from ...clients.worker.types import ChatML from ...common.exceptions.sessions import SessionNotFoundError from ...common.protocol.entries import Entry from ...common.protocol.sessions import SessionData from ...common.utils.template import render_template from ...common.utils.json import CustomJSONEncoder +from ...common.utils.messages import stringify_content from ...env import ( - summarization_tokens_threshold, docs_embedding_service_url, docs_embedding_model_id, ) @@ -36,6 +38,7 @@ from ...models.session.session_data import get_session_data from ...models.session.get_cached_response import get_cached_response from ...models.session.set_cached_response import set_cached_response +from ...exceptions import PromptTooBigError from .exceptions import InputTooBigError from .protocol import Settings @@ -115,8 +118,8 @@ def _remove_messages( return result, token_count - def truncate( - self, messages: list[Entry], summarization_tokens_threshold: int + def _truncate_context( + self, messages: list[Entry], summarization_tokens_threshold: int | None ) -> list[Entry]: def rm_thoughts(m): return m.role == "system" and m.name == "thought" @@ -124,6 +127,9 @@ def rm_thoughts(m): def rm_user_assistant(m): return m.role in ("user", "assistant") + if summarization_tokens_threshold is None: + return messages + token_count = reduce(lambda c, e: (e.token_count or 0) + c, messages, 0) if token_count <= summarization_tokens_threshold: @@ -169,7 +175,8 @@ async def run( # Generate response response = await self.generate( - self.truncate(init_context, summarization_tokens_threshold), final_settings + self._truncate_context(init_context, final_settings.token_budget), + final_settings, ) # Save response to session @@ -218,23 +225,17 @@ async def forward( new_input: list[Entry], settings: Settings, ) -> tuple[list[ChatML], Settings, DocIds]: + if session_data is not None: + settings.token_budget = session_data.token_budget + settings.context_overflow = session_data.context_overflow + stringified_input = [] for msg in new_input: - content = "" - if isinstance(msg.content, list): - content = " ".join( - [part.text for part in msg.content if part.type == "text"] - ) - elif isinstance(msg.content, str): - content = msg.content - elif isinstance(msg.content, dict) and msg.content["type"] == "text": - content = cast(str, msg.content["text"]) - stringified_input.append( ( msg.role, msg.name, - content, + stringify_content(msg.content), ) ) @@ -461,10 +462,22 @@ async def backward( ) entries.append(new_entry) + bg_task = None + + if ( + final_settings.token_budget is not None + and total_tokens >= final_settings.token_budget + ): + if final_settings.context_overflow == "truncate": + bg_task = partial(run_truncation_task, final_settings.token_budget) + elif final_settings.context_overflow == "adaptive": + bg_task = run_summarization_task + else: + raise PromptTooBigError(total_tokens, final_settings.token_budget) + add_entries_query(entries) - if total_tokens >= summarization_tokens_threshold: - return run_summarization_task + return bg_task class PlainCompletionSession(BaseSession): diff --git a/agents-api/agents_api/worker/__main__.py b/agents-api/agents_api/worker/__main__.py index 587bab7a1..02a588c1a 100644 --- a/agents-api/agents_api/worker/__main__.py +++ b/agents-api/agents_api/worker/__main__.py @@ -18,6 +18,7 @@ from ..activities.relationship_summary import relationship_summary from ..activities.salient_questions import salient_questions from ..activities.embed_docs import embed_docs +from ..activities.truncation import truncation from ..env import ( temporal_endpoint, temporal_task_queue, @@ -33,6 +34,7 @@ from ..workflows.mem_rating import MemRatingWorkflow from ..workflows.relationship_summary import RelationshipSummaryWorkflow from ..workflows.salient_questions import SalientQuestionsWorkflow +from ..workflows.truncation import TruncationWorkflow async def main(): @@ -72,6 +74,7 @@ async def main(): RelationshipSummaryWorkflow, SalientQuestionsWorkflow, EmbedDocsWorkflow, + TruncationWorkflow, ], activities=[ summarization, @@ -82,6 +85,7 @@ async def main(): relationship_summary, salient_questions, embed_docs, + truncation, ], ) diff --git a/agents-api/agents_api/workflows/truncation.py b/agents-api/agents_api/workflows/truncation.py new file mode 100644 index 000000000..6057eec38 --- /dev/null +++ b/agents-api/agents_api/workflows/truncation.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 + + +from datetime import timedelta +from temporalio import workflow + +with workflow.unsafe.imports_passed_through(): + from ..activities.truncation import truncation + + +@workflow.defn +class TruncationWorkflow: + @workflow.run + async def run(self, session_id: str, token_count_threshold: int) -> None: + return await workflow.execute_activity( + truncation, + args=[session_id, token_count_threshold], + schedule_to_close_timeout=timedelta(seconds=600), + ) diff --git a/agents-api/migrations/migrate_1717239610_token_budget.py b/agents-api/migrations/migrate_1717239610_token_budget.py new file mode 100644 index 000000000..c042c56e5 --- /dev/null +++ b/agents-api/migrations/migrate_1717239610_token_budget.py @@ -0,0 +1,67 @@ +# /usr/bin/env python3 + +MIGRATION_ID = "token_budget" +CREATED_AT = 1717239610.622555 + +update_sessions = { + "up": """ + ?[developer_id, session_id, updated_at, situation, summary, created_at, metadata, render_templates, token_budget, context_overflow] := *sessions{ + developer_id, + session_id, + updated_at, + situation, + summary, + created_at, + metadata, + render_templates, + }, + token_budget = null, + context_overflow = null, + + :replace sessions { + developer_id: Uuid, + session_id: Uuid, + updated_at: Validity default [floor(now()), true], + => + situation: String, + summary: String? default null, + created_at: Float default now(), + metadata: Json default {}, + render_templates: Bool default false, + token_budget: Int? default null, + context_overflow: String? default null, + } + """, + "down": """ + ?[developer_id, session_id, updated_at, situation, summary, created_at, metadata, render_templates] := *sessions{ + developer_id, + session_id, + updated_at, + situation, + summary, + created_at, + metadata, + render_templates, + } + + :replace sessions { + developer_id: Uuid, + session_id: Uuid, + updated_at: Validity default [floor(now()), true], + => + situation: String, + summary: String? default null, + created_at: Float default now(), + metadata: Json default {}, + render_templates: Bool default false, + } + """, +} + + +def up(client): + client.run(update_sessions["up"]) + + +def down(client): + client.run(update_sessions["down"]) diff --git a/agents-api/notebooks/01-revise-entities.ipynb b/agents-api/notebooks/01-revise-entities.ipynb new file mode 100644 index 000000000..00667cb82 --- /dev/null +++ b/agents-api/notebooks/01-revise-entities.ipynb @@ -0,0 +1,539 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from dotenv import load_dotenv\n", + "\n", + "load_dotenv(\".env\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Operations\n", + "- ENTITY: Add or update an entity list containing information about the people, places, things, mentions, present in the conversation\n", + "- TRIM: Trim messages in place ({user: ...} => {user: ...})\n", + "- SUMMARIZE: Combine two or more messages into one summary\n", + "- REMOVE: Safely remove messages from the session" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "from openai import Client\n", + "\n", + "client = Client()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "make_chatml = lambda content, role=\"system\", name=None, **_: {\n", + " key: value\n", + " for key, value in dict(role=role, name=name, content=content).items()\n", + " if value is not None\n", + "}\n", + "\n", + "user = lambda content, name=None: make_chatml(role=\"user\", content=content, name=name)\n", + "assistant = lambda content, name=None: make_chatml(\n", + " role=\"assistant\", content=content, name=name\n", + ")\n", + "system = lambda content, name=None: make_chatml(content, name=name)\n", + "thought = lambda content, name=None: make_chatml(content, name=\"thought\")\n", + "information = lambda content: system(content, name=\"information\")\n", + "summary = lambda content: system(content, name=\"summary\")\n", + "entities = lambda content: system(content, name=\"entity\")" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "chat_session = []\n", + "chat_summaries = []\n", + "session_summary_map: list[tuple[tuple[list, int], tuple[list, int]]] = [\n", + " # ((chat_session: 0): (chat_summaries: 0))\n", + "]\n", + "generate = (\n", + " lambda history, model=\"gpt-4-turbo\", **kwargs: client.chat.completions.create(\n", + " model=model, messages=history, **kwargs\n", + " )\n", + " .choices[0]\n", + " .message.__dict__\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "from pprint import pprint\n", + "\n", + "\n", + "def chat():\n", + " while (user_input := input(\"You: \")) != \"bye\":\n", + " chat_session.append(user(user_input))\n", + " result = generate(chat_session)\n", + " print(f\"GPT: {result['content']}\")\n", + " chat_session.append(make_chatml(**result))" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "\n", + "example_chat = [\n", + " {\n", + " \"role\": \"system\",\n", + " \"content\": \"just have a casual chat with a friend friend\",\n", + " \"index\": 0,\n", + " },\n", + " {\"role\": \"user\", \"content\": \"yo\", \"index\": 1, \"name\": \"Camille\"},\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Hey, how's it going?\",\n", + " \"index\": 2,\n", + " \"name\": \"JaneBot\",\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"sup\",\n", + " \"index\": 3,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Not much, just working and trying to stay busy. How about you?\",\n", + " \"index\": 4,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"what you think about elon?\",\n", + " \"index\": 5,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Elon Musk is definitely a fascinating and polarizing figure. He's accomplished a lot in the tech and space industries with companies like Tesla and SpaceX. What do you think about him?\",\n", + " \"index\": 6,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"very polarizing, dude is nuts but in a fun way\",\n", + " \"index\": 7,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Haha, yeah, that's a pretty accurate description of him. He definitely knows how to keep things interesting and push boundaries. It's always exciting to see what he'll come up with next.\",\n", + " \"index\": 8,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"i am glad he exists\",\n", + " \"index\": 9,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"For sure, he's definitely made a huge impact on various industries. It's always interesting to see how his projects and ideas continue to evolve.\",\n", + " \"index\": 10,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"what are your thoughts on bananas?\",\n", + " \"index\": 11,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"I actually love bananas! They're a great snack, full of nutrients and easy to eat on the go. How about you, do you like bananas?\",\n", + " \"index\": 12,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"super much. i have a tattoo of a banana on my arm\",\n", + " \"index\": 13,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"That's awesome! A banana tattoo sounds like a fun and unique choice. It must be a great conversation starter. Do you have any other food-related tattoos?\",\n", + " \"index\": 14,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"yeah, your mom\",\n", + " \"index\": 15,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Haha, good one! You got me there. Feel free to keep the jokes coming.\",\n", + " \"index\": 16,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"lulz, u funny\",\n", + " \"index\": 17,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Glad I could make you laugh! It's always great to share a joke or two. Anything else on your mind, or are we just going with the flow of the conversation?\",\n", + " \"index\": 18,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"ok if I give you a long story, can you guess its title?\",\n", + " \"index\": 19,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Sure, I can give it a try! Go ahead and tell me your story, and I'll see if I can guess the title.\",\n", + " \"index\": 20,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"zero is a beautiful number. Not because it is round and cute (that could be an argument for it nevertheless) but because what it signifies. It marks the beginning of something. It marks the lowest something, or someone can go. It is the ultimate foundation to build anything upon. Over last several years, I’ve started several things from scratch and have failed at many (thus going back to zero), and I’ve realized there’s nothing more liberating than being at zero because the only way from zero is upwards. A very good friend once told me, “Don’t worry if you’ve failed. Rockets that touch the sky always launch from the ground.” As J K Rowling, one of my favorite authors says, “Rock bottom became the solid foundation on which I rebuilt my life.” While zero is liberating, thrilling and exciting, it sometimes also is daunting and overwhelming. Sometimes, I have found myself afraid to do something because I was comfortable being at zero and the task to go from zero to one seemed unnerving. This challenge of writing twenty-six stories was one such adventure. I remember it was the first of April when I decided to pen down a story for each letter of the alphabet. I was afraid if I was unknowingly planning to fool myself on April 1st. I had no clue what to write even for the first letter of the alphabet. I was afraid I’d ruin twenty-six stories if I begin writing them just for the sake of writing. What gave me the courage to take up the challenge was to lower the expectations that I’d have from these stories. My purpose was not to write twenty-six bestseller stories. Mine was to make it a habit of writing every day. Some days everything that came out of my pen was garbage, and on a few days, I loved what my hands typed on the blank paper. And today, with this last story, I am back at zero — a solid foundation for the next adventure. Writing has become my daily habit, and I can remember to write even without my calendar sending me a reminder. I am curious what could I make out of this habit. Shall I start another writing adventure? Will it be a similar series? Will be a novel (long due now)? Or something different altogether? Whatever it’d be, I guess I’ll be little less nervous to begin whatever comes next. I am at zero again, and the only way to go from here is upwards. Realizing that there’ll be one less thing in my daily routine, I feel a particular kind of guilt. It’s the kind of guilt that you feel when you have an ice-cream without telling your younger sibling about it. You kind of like it that you had the ice-cream but also feel guilty for hiding it from them. On the new adventure, whatever it’d be, it’s time to buy an ice-cream for them this time.\",\n", + " \"index\": 21,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": 'Based on the themes of starting anew, embracing failure, and the journey from zero to one, I would guess that the title of this story is \"Back to One.\" It seems to capture the essence of the protagonist\\'s experience and mindset throughout the story. How did I do?',\n", + " \"index\": 22,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"ok that's cool but you are wrong. anyway what number am I thinking of?\",\n", + " \"index\": 23,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Hmm, I'll take a wild guess and say you're thinking of the number 7. Did I get it right?\",\n", + " \"index\": 24,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"no\",\n", + " \"index\": 25,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Alright, I'll give it another shot. How about the number 3?\",\n", + " \"index\": 26,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"no\",\n", + " \"index\": 27,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"I'll try one more time - is the number you're thinking of 9?\",\n", + " \"index\": 28,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"no\",\n", + " \"index\": 29,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Looks like I haven't quite nailed it yet! Do you mind sharing which number you had in mind?\",\n", + " \"index\": 30,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"no\",\n", + " \"index\": 31,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Fair enough, keeping that mystery alive! If you ever feel like sharing, just let me know. Anything else on your mind or any other games you'd like to play?\",\n", + " \"index\": 32,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"yes, write an essay about me from your experience with me so far\",\n", + " \"index\": 33,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"From my interactions with you so far, I can tell that you have a great sense of humor and enjoy playful banter. You seem open to random and fun conversations, and you're not afraid to keep things interesting with unexpected twists and turns.\\n\\nYour creativity shines through in the way you approach different topics, and you have a knack for surprising me with your responses. You're also quite adept at changing the direction of the conversation while maintaining a light and friendly tone.\\n\\nOverall, chatting with you has been enjoyable and entertaining, and I appreciate the lighthearted and casual vibe you bring to our interactions. I look forward to more fun conversations with you in the future!\",\n", + " \"index\": 34,\n", + " },\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: add and optimise the Chain of Thought\n", + "example_chain_of_thought = \"\"\"\\\n", + "Planning step by step:\n", + "To add context for future entries, we should add a section at the top which outlines the main entities in the session. These entities are the main people, places or things that are most relevant to the conversation.\n", + "We should also make sure to add context about each entity.\n", + "\"\"\"\n", + "\n", + "example_entities = [\n", + " entities(\n", + " \"\"\"\\\n", + "1. Camille (The user): Humorous, creative, and enjoys playful banter.\n", + "2. JaneBot (The assistant): Engages in lighthearted conversation and tries to guess user's thoughts.\n", + "3. Elon Musk: Polarizing tech and space industry figure.\n", + "4. Bananas: User has a tattoo of one on their arm.\"\"\"\n", + " )\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "chat_session = [system(\"you are a friend who likes to give life advice\")]" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# Load test chat from json file\n", + "import json\n", + "\n", + "with open(\"./test-chat.json\", \"r\") as f:\n", + " chat_session = json.load(f)\n", + "\n", + "for message, index in zip(chat_session, range(1000)):\n", + " message[\"index\"] = index" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "backup_chat = [*chat_session]" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "def get_leaf_nodes(\n", + " chat_session=chat_session,\n", + " chat_summaries=chat_summaries,\n", + " session_summary_map=session_summary_map,\n", + "):\n", + " all_messages = [*chat_session, *chat_summaries]\n", + " non_leaf_nodes = [source[idx] for (source, idx), _ in session_summary_map]\n", + " remaining = [msg for msg in all_messages if msg not in non_leaf_nodes]\n", + " return remaining" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "def add_summary(summary_obj, targets):\n", + " chat_summaries.append(summary_obj)\n", + " current_idx = len(chat_summaries) - 1\n", + "\n", + " for target in targets:\n", + " session_summary_map.append(\n", + " ((chat_session, target), (chat_summaries, current_idx))\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "from pprint import pprint\n", + "import time\n", + "\n", + "\n", + "def get_entities(chat_session=chat_session):\n", + " _sys_msg, *history_to_compact = get_leaf_nodes(chat_session=chat_session)\n", + " history_to_compact = [\n", + " {\"index\": i + 1, **msg} for i, msg in enumerate(history_to_compact)\n", + " ]\n", + " system_prompt = f\"\"\"\\\n", + "You are given a session history of a chat between a user and gpt-4-turbo, a Large Language Model.\n", + "\n", + "Entities should include (but not be limited to):\n", + "- Characters in the conversation: Assistant, User1, User2\n", + "- People references or spoken about\n", + "- Objects discussed about\n", + "- Places of interest\n", + "\n", + "\n", + "Your goal is to identify the main entities in the session. These entities are the main people, places or things that are most relevant to the conversation.\n", + "\n", + "- You may identify and isolate important entities discussed in the conversation.\n", + "- You may add new entities that are not present in the conversation but are important to the context of the conversation.\n", + "- You may provide some context about the entity explaining it's relevance to the conversation.\n", + "\n", + "\n", + "{json.dumps(example_chat, indent=2)}\n", + "\n", + "\n", + "\n", + "{example_chain_of_thought}\n", + "\n", + "\n", + "\n", + "{json.dumps(example_entities, indent=2)}\n", + "\n", + "\"\"\".strip()\n", + "\n", + " user_message = f\"\"\"\\\n", + "\n", + "{json.dumps(history_to_compact, indent=2)}\n", + "\n", + "\n", + "\n", + "\"\"\"\n", + " messages = [system(system_prompt), user(user_message)]\n", + "\n", + " print(\"Starting CoT generation\")\n", + " cot_result = generate(messages, model=\"gpt-4-turbo\", stop=[\"\n", + "\"\"\".strip()\n", + "\n", + " messages.append(user(start_message))\n", + "\n", + " print(\"Starting chatml generation\")\n", + " result = generate(messages, model=\"gpt-4-turbo\", temperature=0.1, stop=[\" {user: ...})\n", + "- SUMMARIZE: Combine two or more messages into one summary\n", + "- REMOVE: Safely remove messages from the session" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from openai import Client\n", + "\n", + "client = Client()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "make_chatml = lambda content, role=\"system\", name=None, **_: {\n", + " key: value\n", + " for key, value in dict(role=role, name=name, content=content).items()\n", + " if value is not None\n", + "}\n", + "\n", + "user = lambda content, name=None: make_chatml(role=\"user\", content=content, name=name)\n", + "assistant = lambda content, name=None: make_chatml(\n", + " role=\"assistant\", content=content, name=name\n", + ")\n", + "system = lambda content, name=None: make_chatml(content, name=name)\n", + "thought = lambda content, name=None: make_chatml(content, name=\"thought\")\n", + "information = lambda content: system(content, name=\"information\")\n", + "summary = lambda content: system(content, name=\"summary\")\n", + "entities = lambda content: system(content, name=\"entity\")" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "chat_session = []\n", + "chat_summaries = []\n", + "session_summary_map: list[tuple[tuple[list, int], tuple[list, int]]] = [\n", + " # ((chat_session: 0): (chat_summaries: 0))\n", + "]\n", + "generate = (\n", + " lambda history, model=\"gpt-4-turbo\", **kwargs: client.chat.completions.create(\n", + " model=model, messages=history, **kwargs\n", + " )\n", + " .choices[0]\n", + " .message.__dict__\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "from pprint import pprint\n", + "\n", + "\n", + "def chat():\n", + " while (user_input := input(\"You: \")) != \"bye\":\n", + " chat_session.append(user(user_input))\n", + " result = generate(chat_session)\n", + " print(f\"GPT: {result['content']}\")\n", + " chat_session.append(make_chatml(**result))" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "\n", + "example_chat = [\n", + " {\n", + " \"role\": \"system\",\n", + " \"content\": \"just have a casual chat with a friend friend\",\n", + " \"index\": 0,\n", + " },\n", + " {\"role\": \"user\", \"content\": \"yo\", \"index\": 1, \"name\": \"Camille\"},\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Hey, how's it going?\",\n", + " \"index\": 2,\n", + " \"name\": \"JaneBot\",\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"sup\",\n", + " \"index\": 3,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Not much, just working and trying to stay busy. How about you?\",\n", + " \"index\": 4,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"what you think about elon?\",\n", + " \"index\": 5,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Elon Musk is definitely a fascinating and polarizing figure. He's accomplished a lot in the tech and space industries with companies like Tesla and SpaceX. What do you think about him?\",\n", + " \"index\": 6,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"very polarizing, dude is nuts but in a fun way\",\n", + " \"index\": 7,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Haha, yeah, that's a pretty accurate description of him. He definitely knows how to keep things interesting and push boundaries. It's always exciting to see what he'll come up with next.\",\n", + " \"index\": 8,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"i am glad he exists\",\n", + " \"index\": 9,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"For sure, he's definitely made a huge impact on various industries. It's always interesting to see how his projects and ideas continue to evolve.\",\n", + " \"index\": 10,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"what are your thoughts on bananas?\",\n", + " \"index\": 11,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"I actually love bananas! They're a great snack, full of nutrients and easy to eat on the go. How about you, do you like bananas?\",\n", + " \"index\": 12,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"super much. i have a tattoo of a banana on my arm\",\n", + " \"index\": 13,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"That's awesome! A banana tattoo sounds like a fun and unique choice. It must be a great conversation starter. Do you have any other food-related tattoos?\",\n", + " \"index\": 14,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"yeah, your mom\",\n", + " \"index\": 15,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Haha, good one! You got me there. Feel free to keep the jokes coming.\",\n", + " \"index\": 16,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"lulz, u funny\",\n", + " \"index\": 17,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Glad I could make you laugh! It's always great to share a joke or two. Anything else on your mind, or are we just going with the flow of the conversation?\",\n", + " \"index\": 18,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"ok if I give you a long story, can you guess its title?\",\n", + " \"index\": 19,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Sure, I can give it a try! Go ahead and tell me your story, and I'll see if I can guess the title.\",\n", + " \"index\": 20,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"zero is a beautiful number. Not because it is round and cute (that could be an argument for it nevertheless) but because what it signifies. It marks the beginning of something. It marks the lowest something, or someone can go. It is the ultimate foundation to build anything upon. Over last several years, I’ve started several things from scratch and have failed at many (thus going back to zero), and I’ve realized there’s nothing more liberating than being at zero because the only way from zero is upwards. A very good friend once told me, “Don’t worry if you’ve failed. Rockets that touch the sky always launch from the ground.” As J K Rowling, one of my favorite authors says, “Rock bottom became the solid foundation on which I rebuilt my life.” While zero is liberating, thrilling and exciting, it sometimes also is daunting and overwhelming. Sometimes, I have found myself afraid to do something because I was comfortable being at zero and the task to go from zero to one seemed unnerving. This challenge of writing twenty-six stories was one such adventure. I remember it was the first of April when I decided to pen down a story for each letter of the alphabet. I was afraid if I was unknowingly planning to fool myself on April 1st. I had no clue what to write even for the first letter of the alphabet. I was afraid I’d ruin twenty-six stories if I begin writing them just for the sake of writing. What gave me the courage to take up the challenge was to lower the expectations that I’d have from these stories. My purpose was not to write twenty-six bestseller stories. Mine was to make it a habit of writing every day. Some days everything that came out of my pen was garbage, and on a few days, I loved what my hands typed on the blank paper. And today, with this last story, I am back at zero — a solid foundation for the next adventure. Writing has become my daily habit, and I can remember to write even without my calendar sending me a reminder. I am curious what could I make out of this habit. Shall I start another writing adventure? Will it be a similar series? Will be a novel (long due now)? Or something different altogether? Whatever it’d be, I guess I’ll be little less nervous to begin whatever comes next. I am at zero again, and the only way to go from here is upwards. Realizing that there’ll be one less thing in my daily routine, I feel a particular kind of guilt. It’s the kind of guilt that you feel when you have an ice-cream without telling your younger sibling about it. You kind of like it that you had the ice-cream but also feel guilty for hiding it from them. On the new adventure, whatever it’d be, it’s time to buy an ice-cream for them this time.\",\n", + " \"index\": 21,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": 'Based on the themes of starting anew, embracing failure, and the journey from zero to one, I would guess that the title of this story is \"Back to One.\" It seems to capture the essence of the protagonist\\'s experience and mindset throughout the story. How did I do?',\n", + " \"index\": 22,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"ok that's cool but you are wrong. anyway what number am I thinking of?\",\n", + " \"index\": 23,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Hmm, I'll take a wild guess and say you're thinking of the number 7. Did I get it right?\",\n", + " \"index\": 24,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"no\",\n", + " \"index\": 25,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Alright, I'll give it another shot. How about the number 3?\",\n", + " \"index\": 26,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"no\",\n", + " \"index\": 27,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"I'll try one more time - is the number you're thinking of 9?\",\n", + " \"index\": 28,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"no\",\n", + " \"index\": 29,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Looks like I haven't quite nailed it yet! Do you mind sharing which number you had in mind?\",\n", + " \"index\": 30,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"no\",\n", + " \"index\": 31,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Fair enough, keeping that mystery alive! If you ever feel like sharing, just let me know. Anything else on your mind or any other games you'd like to play?\",\n", + " \"index\": 32,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"yes, write an essay about me from your experience with me so far\",\n", + " \"index\": 33,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"From my interactions with you so far, I can tell that you have a great sense of humor and enjoy playful banter. You seem open to random and fun conversations, and you're not afraid to keep things interesting with unexpected twists and turns.\\n\\nYour creativity shines through in the way you approach different topics, and you have a knack for surprising me with your responses. You're also quite adept at changing the direction of the conversation while maintaining a light and friendly tone.\\n\\nOverall, chatting with you has been enjoyable and entertaining, and I appreciate the lighthearted and casual vibe you bring to our interactions. I look forward to more fun conversations with you in the future!\",\n", + " \"index\": 34,\n", + " },\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: add and optimise the Chain of Thought\n", + "example_chain_of_thought = \"\"\"\\\n", + "Planning step by step:\n", + "To remove unnecessary content in the message history, we should go through each message and trim it to make it concise if it is too long. Longer messages need to get converted into smaller, more compact version of them.\n", + "It is important to make keep the tone, setting and flow of the conversation consistent while trimming the messages.\n", + "For longer messages, tags should be used to indicate that it's a summarised message.\n", + "\n", + "Let me walk through each message to decide what to do for each one.\n", + "\"\"\"\n", + "\n", + "example_trimmed_messages = [\n", + " *example_chat[0:8],\n", + " assistant(\"Haha accurate. He does push boundaries and keep things interesting!\"),\n", + " *example_chat[9:10],\n", + " assistant(\n", + " \"For sure, he's definitely made a huge impact in different industries. Excited to see what he'll come up with next\"\n", + " ),\n", + " *example_chat[11:18],\n", + " assistant(\n", + " \"Glad I could make you laugh! It's always nice to share a joke or two. What else is up?\"\n", + " ),\n", + " *example_chat[19:21],\n", + " user(\n", + " \"\"\"\n", + "- Zero is a beautiful number because it signifies the beginning, the lowest point one can reach, and the ultimate foundation to build anything upon\n", + "- Over the years, I've started numerous endeavors from scratch (zero) and failed miserably at many, thus going back to zero\n", + "- I've realized there's nothing more liberating than being at zero, as the only direction from there is upwards\n", + "- The challenge of penning 26 stories, one for each alphabet letter, seemed incredibly daunting when I was at zero with no ideas whatsoever\n", + "- Lowering my expectations helped - my purpose was not to craft 26 bestsellers but to cultivate a daily writing habit\n", + "- Certain days, everything that flowed from my pen felt like utter garbage, while on a few blessed days, I loved what my hands typed\n", + "- With this final story, I find myself back at zero - a solid foundation primed for my next adventure into the writing world\n", + "- Writing has transformed into an ingrained daily habit, no longer requiring calendar reminders to prompt me\n", + "- I'm brimming with curiosity about what form my next writing project will take - another thematic series? My long-overdue novel? Or something entirely unprecedented?\n", + "- Though a tinge of guilt lingers for this routine coming to an end, akin to secretly devouring ice cream without my younger sibling\n", + "- For my next foray, I'm resolute about \"buying an ice cream\" and sharing the entire journey with them this time around\n", + "\n", + "\"\"\"\n", + " ),\n", + " *example_chat[22:34],\n", + " assistant(\n", + " \"\"\"\n", + "From my interactions so far, here's what I think of you:\n", + "- Great sense of humor, enjoy playful banter\n", + "- Open to random, fun conversations \n", + "- Creativity shines through, surprising responses\n", + "- Adept at changing conversation direction seamlessly\n", + "- Maintain a light, friendly tone throughout\n", + "- Highly engaging and enjoyable interactions\n", + "- Look forward to more amusing conversations!\n", + "\n", + "\"\"\"\n", + " ),\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "chat_session = [system(\"you are a friend who likes to give life advice\")]" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# Load test chat from json file\n", + "import json\n", + "\n", + "with open(\"./test-chat.json\", \"r\") as f:\n", + " chat_session = json.load(f)\n", + "\n", + "for message, index in zip(chat_session, range(1000)):\n", + " message[\"index\"] = index" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "backup_chat = [*chat_session]" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "def get_leaf_nodes(\n", + " chat_session=chat_session,\n", + " chat_summaries=chat_summaries,\n", + " session_summary_map=session_summary_map,\n", + "):\n", + " all_messages = [*chat_session, *chat_summaries]\n", + " non_leaf_nodes = [source[idx] for (source, idx), _ in session_summary_map]\n", + " remaining = [msg for msg in all_messages if msg not in non_leaf_nodes]\n", + " return remaining" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "def add_summary(summary_obj, targets):\n", + " chat_summaries.append(summary_obj)\n", + " current_idx = len(chat_summaries) - 1\n", + "\n", + " for target in targets:\n", + " session_summary_map.append(\n", + " ((chat_session, target), (chat_summaries, current_idx))\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "from pprint import pprint\n", + "import time\n", + "\n", + "\n", + "def trim_messages(chat_session=chat_session):\n", + " _sys_msg, *history_to_compact = get_leaf_nodes(chat_session=chat_session)\n", + " history_to_compact = [\n", + " {\"index\": i + 1, **msg} for i, msg in enumerate(history_to_compact)\n", + " ]\n", + " system_prompt = f\"\"\"\\\n", + "You are given a session history of a chat between a user and gpt-4-turbo, a Large Language Model.\n", + "\n", + "Your goal is to walk through each message and trim it if required.\n", + "Trimming may be required when:\n", + "- A message is too verbose and can be re-written in the character's tone\n", + "- A message is akin to long form paragraph and can be \"trimmed\" to descriptive bullet points.\n", + "\n", + "When trimming longer form messages, tag should be used in order to indicate the rewrite.\n", + "\n", + "Your task is to review the conversation, identify messages that could benefit from trimming based on the criteria above, and provide a trimmed version using the tags. This will help make the conversation more concise and focused.\n", + "\n", + "\n", + "{json.dumps(example_chat, indent=2)}\n", + "\n", + "\n", + "\n", + "{example_chain_of_thought}\n", + "\n", + "\n", + "\n", + "{json.dumps(example_trimmed_messages, indent=2)}\n", + "\n", + "\"\"\".strip()\n", + "\n", + " user_message = f\"\"\"\\\n", + "\n", + "{json.dumps(history_to_compact, indent=2)}\n", + "\n", + "\n", + "\n", + "\"\"\"\n", + " messages = [system(system_prompt), user(user_message)]\n", + "\n", + " print(\"Starting CoT generation\")\n", + " cot_result = generate(messages, model=\"gpt-4-turbo\", stop=[\"\n", + "\"\"\".strip()\n", + "\n", + " messages.append(user(start_message))\n", + "\n", + " print(\"Starting chatml generation\")\n", + " result = generate(messages, model=\"gpt-4-turbo\", temperature=0.1, stop=[\" {user: ...})\n", + "- SUMMARIZE: Combine two or more messages into one summary\n", + "- REMOVE: Safely remove messages from the session" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Helper functions and Setup" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from openai import Client\n", + "\n", + "client = Client()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "make_chatml = lambda content, role=\"system\", name=None, index=None, **_: {\n", + " key: value\n", + " for key, value in dict(role=role, name=name, content=content).items()\n", + " if value is not None\n", + "}\n", + "\n", + "user = lambda content, name=None, index=None: make_chatml(\n", + " role=\"user\", content=content, name=name, index=index\n", + ")\n", + "assistant = lambda content, name=None, index=None: make_chatml(\n", + " role=\"assistant\", content=content, name=name, index=index\n", + ")\n", + "system = lambda content, name=None, index=None: make_chatml(\n", + " content, name=name, index=index\n", + ")\n", + "thought = lambda content, name=None: make_chatml(content, name=\"thought\")\n", + "information = lambda content: system(content, name=\"information\")\n", + "summary = lambda content, index=None: system(content, name=\"summary\", index=index)\n", + "entities = lambda content: system(content, name=\"entity\")" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "chat_session = []\n", + "chat_summaries = []\n", + "session_summary_map: list[tuple[tuple[list, int], tuple[list, int]]] = [\n", + " # ((chat_session: 0): (chat_summaries: 0))\n", + "]\n", + "generate = (\n", + " lambda history, model=\"gpt-4-turbo\", **kwargs: client.chat.completions.create(\n", + " model=model, messages=history, **kwargs\n", + " )\n", + " .choices[0]\n", + " .message.__dict__\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "from pprint import pprint\n", + "\n", + "\n", + "def chat():\n", + " while (user_input := input(\"You: \")) != \"bye\":\n", + " chat_session.append(user(user_input))\n", + " result = generate(chat_session)\n", + " print(f\"GPT: {result['content']}\")\n", + " chat_session.append(make_chatml(**result))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## One-Shot Example Chat" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "\n", + "example_chat = [\n", + " {\n", + " \"role\": \"system\",\n", + " \"content\": \"just have a casual chat with a friend friend\",\n", + " \"index\": 0,\n", + " },\n", + " {\"role\": \"user\", \"content\": \"yo\", \"index\": 1, \"name\": \"Camille\"},\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Hey, how's it going?\",\n", + " \"index\": 2,\n", + " \"name\": \"JaneBot\",\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"sup\",\n", + " \"index\": 3,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Not much, just working and trying to stay busy. How about you?\",\n", + " \"index\": 4,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"what you think about elon?\",\n", + " \"index\": 5,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Elon Musk is definitely a fascinating and polarizing figure. He's accomplished a lot in the tech and space industries with companies like Tesla and SpaceX. What do you think about him?\",\n", + " \"index\": 6,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"very polarizing, dude is nuts but in a fun way\",\n", + " \"index\": 7,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Haha, yeah, that's a pretty accurate description of him. He definitely knows how to keep things interesting and push boundaries. It's always exciting to see what he'll come up with next.\",\n", + " \"index\": 8,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"i am glad he exists\",\n", + " \"index\": 9,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"For sure, he's definitely made a huge impact on various industries. It's always interesting to see how his projects and ideas continue to evolve.\",\n", + " \"index\": 10,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"what are your thoughts on bananas?\",\n", + " \"index\": 11,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"I actually love bananas! They're a great snack, full of nutrients and easy to eat on the go. How about you, do you like bananas?\",\n", + " \"index\": 12,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"super much. i have a tattoo of a banana on my arm\",\n", + " \"index\": 13,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"That's awesome! A banana tattoo sounds like a fun and unique choice. It must be a great conversation starter. Do you have any other food-related tattoos?\",\n", + " \"index\": 14,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"yeah, your mom\",\n", + " \"index\": 15,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Haha, good one! You got me there. Feel free to keep the jokes coming.\",\n", + " \"index\": 16,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"lulz, u funny\",\n", + " \"index\": 17,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Glad I could make you laugh! It's always great to share a joke or two. Anything else on your mind, or are we just going with the flow of the conversation?\",\n", + " \"index\": 18,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"ok if I give you a long story, can you guess its title?\",\n", + " \"index\": 19,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Sure, I can give it a try! Go ahead and tell me your story, and I'll see if I can guess the title.\",\n", + " \"index\": 20,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"zero is a beautiful number. Not because it is round and cute (that could be an argument for it nevertheless) but because what it signifies. It marks the beginning of something. It marks the lowest something, or someone can go. It is the ultimate foundation to build anything upon. Over last several years, I’ve started several things from scratch and have failed at many (thus going back to zero), and I’ve realized there’s nothing more liberating than being at zero because the only way from zero is upwards. A very good friend once told me, “Don’t worry if you’ve failed. Rockets that touch the sky always launch from the ground.” As J K Rowling, one of my favorite authors says, “Rock bottom became the solid foundation on which I rebuilt my life.” While zero is liberating, thrilling and exciting, it sometimes also is daunting and overwhelming. Sometimes, I have found myself afraid to do something because I was comfortable being at zero and the task to go from zero to one seemed unnerving. This challenge of writing twenty-six stories was one such adventure. I remember it was the first of April when I decided to pen down a story for each letter of the alphabet. I was afraid if I was unknowingly planning to fool myself on April 1st. I had no clue what to write even for the first letter of the alphabet. I was afraid I’d ruin twenty-six stories if I begin writing them just for the sake of writing. What gave me the courage to take up the challenge was to lower the expectations that I’d have from these stories. My purpose was not to write twenty-six bestseller stories. Mine was to make it a habit of writing every day. Some days everything that came out of my pen was garbage, and on a few days, I loved what my hands typed on the blank paper. And today, with this last story, I am back at zero — a solid foundation for the next adventure. Writing has become my daily habit, and I can remember to write even without my calendar sending me a reminder. I am curious what could I make out of this habit. Shall I start another writing adventure? Will it be a similar series? Will be a novel (long due now)? Or something different altogether? Whatever it’d be, I guess I’ll be little less nervous to begin whatever comes next. I am at zero again, and the only way to go from here is upwards. Realizing that there’ll be one less thing in my daily routine, I feel a particular kind of guilt. It’s the kind of guilt that you feel when you have an ice-cream without telling your younger sibling about it. You kind of like it that you had the ice-cream but also feel guilty for hiding it from them. On the new adventure, whatever it’d be, it’s time to buy an ice-cream for them this time.\",\n", + " \"index\": 21,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": 'Based on the themes of starting anew, embracing failure, and the journey from zero to one, I would guess that the title of this story is \"Back to One.\" It seems to capture the essence of the protagonist\\'s experience and mindset throughout the story. How did I do?',\n", + " \"index\": 22,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"ok that's cool but you are wrong. anyway what number am I thinking of?\",\n", + " \"index\": 23,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Hmm, I'll take a wild guess and say you're thinking of the number 7. Did I get it right?\",\n", + " \"index\": 24,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"no\",\n", + " \"index\": 25,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Alright, I'll give it another shot. How about the number 3?\",\n", + " \"index\": 26,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"no\",\n", + " \"index\": 27,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"I'll try one more time - is the number you're thinking of 9?\",\n", + " \"index\": 28,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"no\",\n", + " \"index\": 29,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Looks like I haven't quite nailed it yet! Do you mind sharing which number you had in mind?\",\n", + " \"index\": 30,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"no\",\n", + " \"index\": 31,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Fair enough, keeping that mystery alive! If you ever feel like sharing, just let me know. Anything else on your mind or any other games you'd like to play?\",\n", + " \"index\": 32,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"yes, write an essay about me from your experience with me so far\",\n", + " \"index\": 33,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"From my interactions with you so far, I can tell that you have a great sense of humor and enjoy playful banter. You seem open to random and fun conversations, and you're not afraid to keep things interesting with unexpected twists and turns.\\n\\nYour creativity shines through in the way you approach different topics, and you have a knack for surprising me with your responses. You're also quite adept at changing the direction of the conversation while maintaining a light and friendly tone.\\n\\nOverall, chatting with you has been enjoyable and entertaining, and I appreciate the lighthearted and casual vibe you bring to our interactions. I look forward to more fun conversations with you in the future!\",\n", + " \"index\": 34,\n", + " },\n", + "]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Entity Extraction One-Shot Example" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: add and optimise the Chain of Thought\n", + "entity_chain_of_thought = \"\"\"\\\n", + "Planning step by step:\n", + "To add context for future entries, we should add a section at the top which outlines the main entities in the session. These entities are the main people, places or things that are most relevant to the conversation.\n", + "We should also make sure to add context about each entity.\n", + "\"\"\"\n", + "\n", + "example_entity_messages = [\n", + " entities(\n", + " \"\"\"\\\n", + "1. Camille (The user): Humorous, creative, and enjoys playful banter.\n", + "2. JaneBot (The assistant): Engages in lighthearted conversation and tries to guess user's thoughts.\n", + "3. Elon Musk: Polarizing tech and space industry figure.\n", + "4. Bananas: User has a tattoo of one on their arm.\"\"\"\n", + " )\n", + "]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Trim Messages One-Shot Example" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*TODO*\n", + "- only output the index and the content of the message to be changed.\n", + "- [!] Index was not in the output\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: add and optimise the Chain of Thought\n", + "trim_chain_of_thought = \"\"\"\\\n", + "Planning step by step:\n", + "To remove unnecessary content in the message history, we should go through each message and trim it to make it concise if it is too long. Longer messages need to get converted into smaller, more compact version of them.\n", + "It is important to make keep the tone, setting and flow of the conversation consistent while trimming the messages.\n", + "For longer messages, tags should be used to indicate that it's a summarised message.\n", + "\n", + "Let me walk through each message to decide what to do for each one.\n", + "\"\"\"\n", + "\n", + "example_trimmed_messages = [\n", + " *example_chat[0:8],\n", + " assistant(\n", + " \"Haha accurate. He does push boundaries and keep things interesting!\", index=8\n", + " ),\n", + " *example_chat[9:10],\n", + " assistant(\n", + " \"For sure, he's definitely made a huge impact in different industries. Excited to see what he'll come up with next\",\n", + " index=10,\n", + " ),\n", + " *example_chat[11:18],\n", + " assistant(\n", + " \"Glad I could make you laugh! It's always nice to share a joke or two. What else is up?\",\n", + " index=18,\n", + " ),\n", + " *example_chat[19:21],\n", + " user(\n", + " \"\"\"\n", + "- Zero is a beautiful number because it signifies the beginning, the lowest point one can reach, and the ultimate foundation to build anything upon\n", + "- Over the years, I've started numerous endeavors from scratch (zero) and failed miserably at many, thus going back to zero\n", + "- I've realized there's nothing more liberating than being at zero, as the only direction from there is upwards\n", + "- The challenge of penning 26 stories, one for each alphabet letter, seemed incredibly daunting when I was at zero with no ideas whatsoever\n", + "- Lowering my expectations helped - my purpose was not to craft 26 bestsellers but to cultivate a daily writing habit\n", + "- Certain days, everything that flowed from my pen felt like utter garbage, while on a few blessed days, I loved what my hands typed\n", + "- With this final story, I find myself back at zero - a solid foundation primed for my next adventure into the writing world\n", + "- Writing has transformed into an ingrained daily habit, no longer requiring calendar reminders to prompt me\n", + "- I'm brimming with curiosity about what form my next writing project will take - another thematic series? My long-overdue novel? Or something entirely unprecedented?\n", + "- Though a tinge of guilt lingers for this routine coming to an end, akin to secretly devouring ice cream without my younger sibling\n", + "- For my next foray, I'm resolute about \"buying an ice cream\" and sharing the entire journey with them this time around\n", + "\n", + "\"\"\",\n", + " index=21,\n", + " ),\n", + " *example_chat[22:34],\n", + " assistant(\n", + " \"\"\"\n", + "From my interactions so far, here's what I think of you:\n", + "- Great sense of humor, enjoy playful banter\n", + "- Open to random, fun conversations \n", + "- Creativity shines through, surprising responses\n", + "- Adept at changing conversation direction seamlessly\n", + "- Maintain a light, friendly tone throughout\n", + "- Highly engaging and enjoyable interactions\n", + "- Look forward to more amusing conversations!\n", + "\n", + "\"\"\",\n", + " index=34,\n", + " ),\n", + "]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Summarise One-Shot Example" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: add and optimise the Chain of Thought\n", + "summarize_chain_of_thought_example = \"\"\"\\\n", + "Planning step by step:\n", + "- To add context for future entries, let's add one at the top which outlines the main entities in the session.\n", + "- We can replace entries with index 1,2,3,4 with a summary of those messages.\n", + "- We can replace entries with index 5,6,7,8 similarly.\n", + "- It could be disruptive to remove messages with index 9-16 because that might lose the joke's context.\n", + "- We can safely summarize entries with index 17,18 and remove them.\n", + "- We can safely remove message with index 20.\n", + "- We should keep entry with index 21 because it's given by the user and they might ask about it again.\n", + "- We should keep the assistant's response in message with index 22 to keep the context.\n", + "- Messages with index 23-32 are repetitive and should be summarized.\n", + "- We should retain message with index 33 since it's a direct request from the user.\n", + "- We can safely summarize message with index 34's essay into just the salient points only.\n", + "\"\"\"\n", + "\n", + "example_summarized_messages = [\n", + " summary(\n", + " \"Event: Camille says hi to JaneBot and they reply that they are working and trying to stay busy.\"\n", + " ),\n", + " summary(\n", + " \"Event: They discuss Elon Musk and agree that he can be a polarizing personality.\"\n", + " ),\n", + " *example_chat[9:17],\n", + " summary(\"Event: Camille appreciates JaneBot's sense of humor.\"),\n", + " *example_chat[21:23],\n", + " summary(\n", + " 'Event: Camille asks JaneBot to play \"What number I am thinking of?\" game but she keeps saying \"no\" to all guesses which JaneBot finds really funny.'\n", + " ),\n", + " example_chat[33],\n", + " summary(\n", + " \"\"\"Event: JaneBot wrote an essay about Camille. Summary of the essay:\n", + "1. You have a great sense of humor and enjoy playful, lighthearted banter in conversations.\n", + "2. Your creativity is evident in how you approach topics in unexpected ways and keep conversations interesting.\n", + "3. Chatting with you is enjoyable due to the casual, friendly tone you bring to interactions.\"\"\"\n", + " ),\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# chat_session = [system(\"you are a friend who likes to give life advice\")]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Loading Test Chat JSON" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "# Test Chat File\n", + "import json\n", + "\n", + "with open(\"./test-chat.json\", \"r\") as f:\n", + " chat_session = json.load(f)\n", + "\n", + "for index, message in enumerate(chat_session):\n", + " message[\"index\"] = index + 1" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "backup_chat = [*chat_session]" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "def get_leaf_nodes(\n", + " chat_session=chat_session,\n", + " chat_summaries=chat_summaries,\n", + " session_summary_map=session_summary_map,\n", + "):\n", + " all_messages = [*chat_session, *chat_summaries]\n", + " non_leaf_nodes = [source[idx] for (source, idx), _ in session_summary_map]\n", + " remaining = [msg for msg in all_messages if msg not in non_leaf_nodes]\n", + " return remaining" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "def add_summary(summary_obj, targets):\n", + " chat_summaries.append(summary_obj)\n", + " current_idx = len(chat_summaries) - 1\n", + "\n", + " for target in targets:\n", + " session_summary_map.append(\n", + " ((chat_session, target), (chat_summaries, current_idx))\n", + " )" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 1: Form Entities" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "from pprint import pprint\n", + "import time\n", + "\n", + "\n", + "def get_entities(chat_session=chat_session):\n", + " _sys_msg, *history_to_compact = get_leaf_nodes(chat_session=chat_session)\n", + " history_to_compact = [\n", + " {\"index\": i + 1, **msg} for i, msg in enumerate(history_to_compact)\n", + " ]\n", + " system_prompt = f\"\"\"\\\n", + "You are given a session history of a chat between a user and gpt-4-turbo, a Large Language Model.\n", + "\n", + "Entities should include (but not be limited to):\n", + "- Characters in the conversation: Assistant, User1, User2\n", + "- People references or spoken about\n", + "- Objects discussed about\n", + "- Places of interest\n", + "\n", + "\n", + "Your goal is to identify the main entities in the session. These entities are the main people, places or things that are most relevant to the conversation.\n", + "\n", + "- You may identify and isolate important entities discussed in the conversation.\n", + "- You may add new entities that are not present in the conversation but are important to the context of the conversation.\n", + "- You may provide some context about the entity explaining it's relevance to the conversation.\n", + "\n", + "\n", + "{json.dumps(example_chat, indent=2)}\n", + "\n", + "\n", + "\n", + "{entity_chain_of_thought}\n", + "\n", + "\n", + "\n", + "{json.dumps(example_entity_messages, indent=2)}\n", + "\n", + "\"\"\".strip()\n", + "\n", + " user_message = f\"\"\"\\\n", + "\n", + "{json.dumps(history_to_compact, indent=2)}\n", + "\n", + "\n", + "\n", + "\"\"\"\n", + " messages = [system(system_prompt), user(user_message)]\n", + "\n", + " print(\"Starting CoT generation\")\n", + " cot_result = generate(messages, model=\"gpt-4-turbo\", stop=[\"\n", + "\"\"\".strip()\n", + "\n", + " messages.append(user(start_message))\n", + "\n", + " print(\"Starting chatml generation\")\n", + " entity_result = generate(\n", + " messages, model=\"gpt-4-turbo\", temperature=0.1, stop=[\" tag should be used in order to indicate the rewrite.\n", + "\n", + "Your task is to review the conversation, identify messages that could benefit from trimming based on the criteria above, and provide a trimmed version using the tags. This will help make the conversation more concise and focused.\n", + "\n", + "\n", + "{json.dumps(example_chat, indent=2)}\n", + "\n", + "\n", + "\n", + "{summarize_chain_of_thought_example}\n", + "\n", + "\n", + "\n", + "{json.dumps(example_trimmed_messages, indent=2)}\n", + "\n", + "\"\"\".strip()\n", + "\n", + " user_message = f\"\"\"\\\n", + "\n", + "{json.dumps(history_to_compact, indent=2)}\n", + "\n", + "\n", + "\n", + "\"\"\"\n", + " messages = [system(system_prompt), user(user_message)]\n", + "\n", + " print(\"Starting CoT generation\")\n", + " cot_result = generate(messages, model=\"gpt-4-turbo\", stop=[\"\n", + "\"\"\".strip()\n", + "\n", + " messages.append(user(start_message))\n", + "\n", + " print(\"Starting chatml generation\")\n", + " trim_result = generate(messages, model=\"gpt-4-turbo\", temperature=0.1, stop=[\"\n", + "- You will be provided with \"Entities\" which are important characters, people, places, things, objects relevant to the conversation.\n", + "- You will make sure to preserve the context for these \"Entities\".\n", + "- You may remove entries in the history that do not contain any crucial information such as small-talk or repeated questions/responses.\n", + "- You will combine multiple entries into a summary strictly as long as that doesn't disrupt the structure of the session.\n", + "- Do not remove content that the user shared if it might be relevant to future messages.\n", + "\n", + "\n", + "\n", + "\n", + "{json.dumps(example_entity_messages, indent=2)}\n", + "\n", + "\n", + "\n", + "{json.dumps(example_chat, indent=2)}\n", + "\n", + "\n", + "\n", + "{summarize_chain_of_thought_example}\n", + "\n", + "\n", + "\n", + "{json.dumps(example_summarized_messages, indent=2)}\n", + "\n", + "\"\"\".strip()\n", + "\n", + " user_message = f\"\"\"\\\n", + "\n", + "{json.dumps(entity_info)}\n", + "\n", + "\n", + "{json.dumps(history_to_compact, indent=2)}\n", + "\n", + "\n", + "\n", + "\"\"\"\n", + " messages = [system(system_prompt), user(user_message)]\n", + "\n", + " print(\"Starting CoT generation\")\n", + " cot_result = generate(messages, model=\"gpt-4-turbo\", stop=[\"\n", + "\"\"\".strip()\n", + "\n", + " messages.append(user(start_message))\n", + "\n", + " print(\"Starting chatml generation\")\n", + " trim_result = generate(\n", + " messages, model=\"gpt-4-turbo\", temperature=0.1, stop=[\"\\n'\n", + " '[\\n'\n", + " ' {\\n'\n", + " ' \"role\": \"system\",\\n'\n", + " ' \"name\": \"summary\",\\n'\n", + " ' \"content\": \"Event: The user discussed finishing \\'Red Dead '\n", + " \"Redemption 2' and particularly enjoyed the last mission. They \"\n", + " 'also talked about favorite missions and characters, specifically '\n", + " 'Arthur over Dutch.\"\\n'\n", + " ' },\\n'\n", + " ' {\\n'\n", + " ' \"index\": 12,\\n'\n", + " ' \"role\": \"user\",\\n'\n", + " ' \"content\": \"im playing helldivers 2. do u know of it\"\\n'\n", + " ' },\\n'\n", + " ' {\\n'\n", + " ' \"index\": 13,\\n'\n", + " ' \"role\": \"assistant\",\\n'\n", + " ' \"content\": \"Yes, Helldivers 2! It\\'s a great choice if '\n", + " \"you're into intense co-op action. The game really ramps up with \"\n", + " 'its twin-stick shooter gameplay, and it\\\\u2019s super fun but '\n", + " 'also quite challenging. Working together with teammates to '\n", + " 'complete those missions can get pretty hectic. How are you '\n", + " 'finding the chaos and team dynamics so far?\"\\n'\n", + " ' },\\n'\n", + " ' {\\n'\n", + " ' \"index\": 14,\\n'\n", + " ' \"role\": \"user\",\\n'\n", + " ' \"content\": \"amazing. my fav build is laser cannon + guard '\n", + " 'dog. what about u\"\\n'\n", + " ' },\\n'\n", + " ' {\\n'\n", + " ' \"index\": 15,\\n'\n", + " ' \"role\": \"assistant\",\\n'\n", + " ' \"content\": \"Nice combo! The laser cannon is awesome for '\n", + " 'tearing through those enemy swarms, and the guard dog drone '\n", + " 'really helps in keeping the smaller threats at bay. I personally '\n", + " 'love using the railgun with a shield backpack. It gives a good '\n", + " 'balance of offense and defense, especially when things get really '\n", + " 'chaotic. What\\'s been the toughest mission for you so far?\"\\n'\n", + " ' },\\n'\n", + " ' {\\n'\n", + " ' \"index\": 16,\\n'\n", + " ' \"role\": \"user\",\\n'\n", + " ' \"content\": \"dude the charger is so difficult to kill.\"\\n'\n", + " ' },\\n'\n", + " ' {\\n'\n", + " ' \"index\": 17,\\n'\n", + " ' \"role\": \"assistant\",\\n'\n", + " ' \"content\": \"Yeah, the Charger can be brutal! They really test '\n", + " \"your reflexes and teamwork. It's all about timing and \"\n", + " 'coordination with your team to bring those heavy hitters down. '\n", + " 'Have you tried using more strategic traps or mines? Sometimes '\n", + " 'setting up the right position with static fields can really make '\n", + " 'a difference against them. How do your squadmates handle it?\"\\n'\n", + " ' },\\n'\n", + " ' {\\n'\n", + " ' \"index\": 18,\\n'\n", + " ' \"role\": \"user\",\\n'\n", + " ' \"content\": \"we just run and gun\"\\n'\n", + " ' },\\n'\n", + " ' {\\n'\n", + " ' \"index\": 19,\\n'\n", + " ' \"role\": \"assistant\",\\n'\n", + " ' \"content\": \"Classic strategy! That can definitely be fun, '\n", + " 'especially in a game as intense as Helldivers 2 where things get '\n", + " 'chaotic fast. Keeping on the move helps a ton. Just make sure '\n", + " \"someone's always got your back! Have you guys tried any of the \"\n", + " 'higher difficulty levels yet, or are you sticking to a certain '\n", + " 'comfort zone for now?\"\\n'\n", + " ' },\\n'\n", + " ' {\\n'\n", + " ' \"role\": \"system\",\\n'\n", + " ' \"name\": \"summary\",\\n'\n", + " ' \"content\": \"Event: The user discussed an Nvidia driver issue, '\n", + " 'particularly its incompatibility with Linux, and the assistant '\n", + " 'provided potential solutions and resources for assistance.\"\\n'\n", + " ' },\\n'\n", + " ' {\\n'\n", + " ' \"index\": 24,\\n'\n", + " ' \"role\": \"user\",\\n'\n", + " ' \"content\": \"yep. see u bye!\"\\n'\n", + " ' },\\n'\n", + " ' {\\n'\n", + " ' \"index\": 25,\\n'\n", + " ' \"role\": \"assistant\",\\n'\n", + " ' \"content\": \"See you, take care! Bye!\"\\n'\n", + " ' }\\n'\n", + " ']\\n',\n", + " 'role': 'assistant'}\n", + "End CoT generation\n", + "Starting chatml generation\n", + "End chatml generation\n" + ] + } + ], + "source": [ + "trimmed_session = json.loads(trimmed_messages[\"content\"])\n", + "entity_info = entities(entity_info[\"content\"])\n", + "\n", + "\n", + "summarized_messages = summarize_messages(\n", + " entity_info=entity_info, chat_session=trimmed_session\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'content': '[\\n'\n", + " ' {\\n'\n", + " ' \"role\": \"system\",\\n'\n", + " ' \"name\": \"summary\",\\n'\n", + " ' \"content\": \"Event: The user discussed finishing \\'Red Dead '\n", + " \"Redemption 2' and particularly enjoyed the last mission. They \"\n", + " 'also talked about favorite missions and characters, specifically '\n", + " 'Arthur over Dutch.\"\\n'\n", + " ' },\\n'\n", + " ' {\\n'\n", + " ' \"index\": 12,\\n'\n", + " ' \"role\": \"user\",\\n'\n", + " ' \"content\": \"im playing helldivers 2. do u know of it\"\\n'\n", + " ' },\\n'\n", + " ' {\\n'\n", + " ' \"index\": 13,\\n'\n", + " ' \"role\": \"assistant\",\\n'\n", + " ' \"content\": \"Yes, Helldivers 2! It\\'s a great choice if '\n", + " \"you're into intense co-op action. The game really ramps up with \"\n", + " 'its twin-stick shooter gameplay, and it\\\\u2019s super fun but '\n", + " 'also quite challenging. Working together with teammates to '\n", + " 'complete those missions can get pretty hectic. How are you '\n", + " 'finding the chaos and team dynamics so far?\"\\n'\n", + " ' },\\n'\n", + " ' {\\n'\n", + " ' \"index\": 14,\\n'\n", + " ' \"role\": \"user\",\\n'\n", + " ' \"content\": \"amazing. my fav build is laser cannon + guard '\n", + " 'dog. what about u\"\\n'\n", + " ' },\\n'\n", + " ' {\\n'\n", + " ' \"index\": 15,\\n'\n", + " ' \"role\": \"assistant\",\\n'\n", + " ' \"content\": \"Nice combo! The laser cannon is awesome for '\n", + " 'tearing through those enemy swarms, and the guard dog drone '\n", + " 'really helps in keeping the smaller threats at bay. I personally '\n", + " 'love using the railgun with a shield backpack. It gives a good '\n", + " 'balance of offense and defense, especially when things get really '\n", + " 'chaotic. What\\'s been the toughest mission for you so far?\"\\n'\n", + " ' },\\n'\n", + " ' {\\n'\n", + " ' \"index\": 16,\\n'\n", + " ' \"role\": \"user\",\\n'\n", + " ' \"content\": \"dude the charger is so difficult to kill.\"\\n'\n", + " ' },\\n'\n", + " ' {\\n'\n", + " ' \"index\": 17,\\n'\n", + " ' \"role\": \"assistant\",\\n'\n", + " ' \"content\": \"Yeah, the Charger can be brutal! They really test '\n", + " \"your reflexes and teamwork. It's all about timing and \"\n", + " 'coordination with your team to bring those heavy hitters down. '\n", + " 'Have you tried using more strategic traps or mines? Sometimes '\n", + " 'setting up the right position with static fields can really make '\n", + " 'a difference against them. How do your squadmates handle it?\"\\n'\n", + " ' },\\n'\n", + " ' {\\n'\n", + " ' \"index\": 18,\\n'\n", + " ' \"role\": \"user\",\\n'\n", + " ' \"content\": \"we just run and gun\"\\n'\n", + " ' },\\n'\n", + " ' {\\n'\n", + " ' \"index\": 19,\\n'\n", + " ' \"role\": \"assistant\",\\n'\n", + " ' \"content\": \"Classic strategy! That can definitely be fun, '\n", + " 'especially in a game as intense as Helldivers 2 where things get '\n", + " 'chaotic fast. Keeping on the move helps a ton. Just make sure '\n", + " \"someone's always got your back! Have you guys tried any of the \"\n", + " 'higher difficulty levels yet, or are you sticking to a certain '\n", + " 'comfort zone for now?\"\\n'\n", + " ' },\\n'\n", + " ' {\\n'\n", + " ' \"role\": \"system\",\\n'\n", + " ' \"name\": \"summary\",\\n'\n", + " ' \"content\": \"Event: The user discussed an Nvidia driver issue, '\n", + " 'particularly its incompatibility with Linux, and the assistant '\n", + " 'provided potential solutions and resources for assistance.\"\\n'\n", + " ' },\\n'\n", + " ' {\\n'\n", + " ' \"index\": 24,\\n'\n", + " ' \"role\": \"user\",\\n'\n", + " ' \"content\": \"yep. see u bye!\"\\n'\n", + " ' },\\n'\n", + " ' {\\n'\n", + " ' \"index\": 25,\\n'\n", + " ' \"role\": \"assistant\",\\n'\n", + " ' \"content\": \"See you, take care! Bye!\"\\n'\n", + " ' }\\n'\n", + " ']',\n", + " 'role': 'assistant'}\n" + ] + } + ], + "source": [ + "pprint(summarized_messages)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "julep", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.14" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/agents-api/notebooks/04-remove-messages.ipynb b/agents-api/notebooks/04-remove-messages.ipynb new file mode 100644 index 000000000..e69de29bb diff --git a/agents-api/notebooks/RecSum-experiments.ipynb b/agents-api/notebooks/RecSum-experiments.ipynb new file mode 100644 index 000000000..43e6cfe33 --- /dev/null +++ b/agents-api/notebooks/RecSum-experiments.ipynb @@ -0,0 +1,686 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "id": "b03a4636-d57e-42e9-8a06-fdb7c6803708", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from dotenv import load_dotenv\n", + "load_dotenv(\"../../.env\")" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "eb80a352-ad21-423c-9284-32b21d271eba", + "metadata": {}, + "outputs": [], + "source": [ + "from openai import Client" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "4619f484-55f6-4122-8e26-27ec9e3506d5", + "metadata": {}, + "outputs": [], + "source": [ + "client = Client()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "fbf3db3a-4ed1-4e71-b1da-e419445f3cc6", + "metadata": {}, + "outputs": [], + "source": [ + "make_chatml = lambda content, role=\"system\", name=None, **_: {\n", + " key: value\n", + " for key, value in dict(role=role, name=name, content=content).items()\n", + " if value is not None\n", + "}\n", + "\n", + "user = lambda content, name=None: make_chatml(role=\"user\", content=content, name=name)\n", + "assistant = lambda content, name=None: make_chatml(role=\"assistant\", content=content, name=name)\n", + "system = lambda content, name=None: make_chatml(content, name=name)\n", + "thought = lambda content: system(content, name=\"thought\")\n", + "information = lambda content: system(content, name=\"information\")\n", + "summary = lambda content: system(content, name=\"summary\")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "a33f6f0f-ce18-4536-b514-b9f6d220f54f", + "metadata": {}, + "outputs": [], + "source": [ + "chat_session = []\n", + "chat_summaries = []\n", + "session_summary_map: list[tuple[tuple[list, int], tuple[list, int]]] = [\n", + " # ((chat_session, 0): (chat_summaries, 1)),\n", + "]\n", + "\n", + "generate = lambda history, model=\"gpt-3.5-turbo\", **kwargs: client.chat.completions.create(messages=history, model=model, **kwargs).choices[0].message.__dict__" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "7bf6bd91-4959-403c-af79-64ad27ae45ee", + "metadata": {}, + "outputs": [], + "source": [ + "from pprint import pprint\n", + "\n", + "def chat():\n", + " while (user_input := input('You: ')) != \"bye\":\n", + " chat_session.append(user(user_input))\n", + " \n", + " result = generate(chat_session)\n", + " print(f\"GPT: {result['content']}\")\n", + " \n", + " chat_session.append(make_chatml(**result))" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "3a14a68e-6d8a-47b2-a58a-03d4bdb793df", + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "example_chat = [\n", + " {\n", + " \"role\": \"system\",\n", + " \"content\": \"just have a casual chat with a friend friend\",\n", + " \"index\": 0,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"yo\",\n", + " \"index\": 1,\n", + " \"name\": \"Camille\"\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Hey, how's it going?\",\n", + " \"index\": 2,\n", + " \"name\": \"JaneBot\"\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"sup\",\n", + " \"index\": 3,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Not much, just working and trying to stay busy. How about you?\",\n", + " \"index\": 4,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"what you think about elon?\",\n", + " \"index\": 5,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Elon Musk is definitely a fascinating and polarizing figure. He's accomplished a lot in the tech and space industries with companies like Tesla and SpaceX. What do you think about him?\",\n", + " \"index\": 6,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"very polarizing, dude is nuts but in a fun way\",\n", + " \"index\": 7,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Haha, yeah, that's a pretty accurate description of him. He definitely knows how to keep things interesting and push boundaries. It's always exciting to see what he'll come up with next.\",\n", + " \"index\": 8,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"i am glad he exists\",\n", + " \"index\": 9,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"For sure, he's definitely made a huge impact on various industries. It's always interesting to see how his projects and ideas continue to evolve.\",\n", + " \"index\": 10,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"what are your thoughts on bananas?\",\n", + " \"index\": 11,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"I actually love bananas! They're a great snack, full of nutrients and easy to eat on the go. How about you, do you like bananas?\",\n", + " \"index\": 12,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"super much. i have a tattoo of a banana on my arm\",\n", + " \"index\": 13,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"That's awesome! A banana tattoo sounds like a fun and unique choice. It must be a great conversation starter. Do you have any other food-related tattoos?\",\n", + " \"index\": 14,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"yeah, your mom\",\n", + " \"index\": 15,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Haha, good one! You got me there. Feel free to keep the jokes coming.\",\n", + " \"index\": 16,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"lulz, u funny\",\n", + " \"index\": 17,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Glad I could make you laugh! It's always great to share a joke or two. Anything else on your mind, or are we just going with the flow of the conversation?\",\n", + " \"index\": 18,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"ok if I give you a long story, can you guess its title?\",\n", + " \"index\": 19,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Sure, I can give it a try! Go ahead and tell me your story, and I'll see if I can guess the title.\",\n", + " \"index\": 20,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"Zero is a beautiful number. Not because it is round and cute (that could be an argument for it nevertheless) but because what it signifies. It marks the beginning of something. It marks the lowest something, or someone can go. It is the ultimate foundation to build anything upon. Over last several years, I’ve started several things from scratch and have failed at many (thus going back to zero), and I’ve realized there’s nothing more liberating than being at zero because the only way from zero is upwards. A very good friend once told me, “Don’t worry if you’ve failed. Rockets that touch the sky always launch from the ground.” As J K Rowling, one of my favorite authors says, “Rock bottom became the solid foundation on which I rebuilt my life.” While zero is liberating, thrilling and exciting, it sometimes also is daunting and overwhelming. Sometimes, I have found myself afraid to do something because I was comfortable being at zero and the task to go from zero to one seemed unnerving. This challenge of writing twenty-six stories was one such adventure. I remember it was the first of April when I decided to pen down a story for each letter of the alphabet. I was afraid if I was unknowingly planning to fool myself on April 1st. I had no clue what to write even for the first letter of the alphabet. I was afraid I’d ruin twenty-six stories if I begin writing them just for the sake of writing. What gave me the courage to take up the challenge was to lower the expectations that I’d have from these stories. My purpose was not to write twenty-six bestseller stories. Mine was to make it a habit of writing every day. Some days everything that came out of my pen was garbage, and on a few days, I loved what my hands typed on the blank paper. And today, with this last story, I am back at zero — a solid foundation for the next adventure. Writing has become my daily habit, and I can remember to write even without my calendar sending me a reminder. I am curious what could I make out of this habit. Shall I start another writing adventure? Will it be a similar series? Will be a novel (long due now)? Or something different altogether? Whatever it’d be, I guess I’ll be little less nervous to begin whatever comes next. I am at zero again, and the only way to go from here is upwards. Realizing that there’ll be one less thing in my daily routine, I feel a particular kind of guilt. It’s the kind of guilt that you feel when you have an ice-cream without telling your younger sibling about it. You kind of like it that you had the ice-cream but also feel guilty for hiding it from them. On the new adventure, whatever it’d be, it’s time to buy an ice-cream for them this time.\",\n", + " \"index\": 21,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Based on the themes of starting anew, embracing failure, and the journey from zero to one, I would guess that the title of this story is \\\"Back to One.\\\" It seems to capture the essence of the protagonist's experience and mindset throughout the story. How did I do?\",\n", + " \"index\": 22,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"ok that's cool but you are wrong. anyway what number am I thinking of?\",\n", + " \"index\": 23,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Hmm, I'll take a wild guess and say you're thinking of the number 7. Did I get it right?\",\n", + " \"index\": 24,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"no\",\n", + " \"index\": 25,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Alright, I'll give it another shot. How about the number 3?\",\n", + " \"index\": 26,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"no\",\n", + " \"index\": 27,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"I'll try one more time - is the number you're thinking of 9?\",\n", + " \"index\": 28,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"no\",\n", + " \"index\": 29,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Looks like I haven't quite nailed it yet! Do you mind sharing which number you had in mind?\",\n", + " \"index\": 30,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"no\",\n", + " \"index\": 31,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"Fair enough, keeping that mystery alive! If you ever feel like sharing, just let me know. Anything else on your mind or any other games you'd like to play?\",\n", + " \"index\": 32,\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"yes, write an essay about me from your experience with me so far\",\n", + " \"index\": 33,\n", + " },\n", + " {\n", + " \"role\": \"assistant\",\n", + " \"content\": \"From my interactions with you so far, I can tell that you have a great sense of humor and enjoy playful banter. You seem open to random and fun conversations, and you're not afraid to keep things interesting with unexpected twists and turns.\\n\\nYour creativity shines through in the way you approach different topics, and you have a knack for surprising me with your responses. You're also quite adept at changing the direction of the conversation while maintaining a light and friendly tone.\\n\\nOverall, chatting with you has been enjoyable and entertaining, and I appreciate the lighthearted and casual vibe you bring to our interactions. I look forward to more fun conversations with you in the future!\",\n", + " \"index\": 34,\n", + " }\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "0f95ee31-835f-4ccf-91b0-1a3a3b94744e", + "metadata": {}, + "outputs": [], + "source": [ + "example_chain_of_thought = \"\"\"\\\n", + "Planning step by step:\n", + "- To add context for future entries, let's add one at the top which outlines the main entities in the session.\n", + "- We can replace entries 1,2,3,4 with a summary of those messages.\n", + "- We can replace entries 5,6,7,8 similarly.\n", + "- It could be disruptive to remove messages 9-16 because that might lose the joke's context.\n", + "- We can safely summarize entries 17,18 and remove them.\n", + "- We can safely remove message 20.\n", + "- We should keep 21 because it's given by the user and they might ask about it again.\n", + "- We should keep the assistant's response in message 22 to keep the context.\n", + "- Messages 23-32 are repetitive and should be summarized.\n", + "- We should retain message 33 since it's a direct request from the user.\n", + "- We can safely summarize message 34's essay into just the salient points only.\n", + "\"\"\"\n", + "\n", + "example_compacted_history = [\n", + " summary(\"\"\"\\\n", + "Main entities in the session:\n", + "1. Camille (The user): Humorous, creative, and enjoys playful banter.\n", + "2. JaneBot (The assistant): Engages in lighthearted conversation and tries to guess user's thoughts.\n", + "3. Elon Musk: Polarizing tech and space industry figure.\n", + "4. Bananas: User has a tattoo of one on their arm.\"\"\"),\n", + " summary(\"Event: Camille says hi to JaneBot and they reply that they are working and trying to stay busy.\"),\n", + " summary(\"Event: They discuss Elon Musk and agree that he can be a polarizing personality.\"),\n", + " *example_chat[9:17],\n", + " summary(\"Event: Camille appreciates JaneBot's sense of humor.\"),\n", + " *example_chat[21:23],\n", + " summary('Event: Camille asks JaneBot to play \"What number I am thinking of?\" game but she keeps saying \"no\" to all guesses which JaneBot finds really funny.'),\n", + " example_chat[33],\n", + " summary(\"\"\"Event: JaneBot wrote an essay about Camille. Summary of the essay:\n", + "1. You have a great sense of humor and enjoy playful, lighthearted banter in conversations.\n", + "2. Your creativity is evident in how you approach topics in unexpected ways and keep conversations interesting.\n", + "3. Chatting with you is enjoyable due to the casual, friendly tone you bring to interactions.\"\"\")\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "0048ada9-ec65-441e-8bda-fb1b03ffcca9", + "metadata": {}, + "outputs": [], + "source": [ + "chat_session = [system(\"you are a friend who likes to give life advice\")]" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "4a348b46-5b93-4911-990d-3e4973c6a340", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "You: hey\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "GPT: Hey! How are you doing?\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "You: good, how about you?\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "GPT: I'm doing well, thank you for asking. Is there anything on your mind that you'd like to talk about or get some advice on?\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "You: no why do you say that? did I sound troubled?\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "GPT: Not at all! I just thought I'd check in and see if there's anything on your mind that you might need some advice or someone to talk to about. But if you're doing well, that's great to hear!\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "You: no I didnt say I was ok just that I hadnt thought of asking for advice yet\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "GPT: Ah, I see. Well, I'm here whenever you need a listening ear or some advice. Just let me know how I can help!\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "You: bye\n" + ] + } + ], + "source": [ + "chat()" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "b1aac632-8a2f-4ce1-b486-33249714159f", + "metadata": {}, + "outputs": [], + "source": [ + "# Load test chat from json file\n", + "import json\n", + "with open(\"./test-chat.json\", 'r') as f:\n", + " chat_session = json.load(f)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "95431b29-73e2-4954-b6fc-1c8814a9249f", + "metadata": {}, + "outputs": [], + "source": [ + "backup_chat = [*chat_session]" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "1eaabfe2-f399-428b-84d2-ed8c237b7d3d", + "metadata": {}, + "outputs": [], + "source": [ + "def get_leaf_nodes(chat_session=chat_session, chat_summaries=chat_summaries, session_summary_map=session_summary_map):\n", + " all_messages = [*chat_session, *chat_summaries]\n", + "\n", + " # Collect non-leaf nodes\n", + " non_leaf_nodes = [\n", + " source[idx]\n", + " for (source, idx), _ in session_summary_map\n", + " ]\n", + " \n", + " # Remove non-leaf nodes\n", + " remaining = [\n", + " msg for msg in all_messages if msg not in non_leaf_nodes\n", + " ]\n", + "\n", + " return remaining" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "2a726b3c-493c-4df5-81a7-6b7b109c222e", + "metadata": {}, + "outputs": [], + "source": [ + "def add_summary(summary_obj, targets):\n", + " chat_summaries.append(summary_obj)\n", + " current_idx = len(chat_summaries) - 1\n", + "\n", + " for target in targets:\n", + " session_summary_map.append(\n", + " ((chat_session, target), (chat_summaries, current_idx))\n", + " )" + ] + }, + { + "cell_type": "markdown", + "id": "013b2104-e546-4acb-9384-3850dbd38b79", + "metadata": {}, + "source": [ + "### Operations\n", + "- ENTITY: Add or update an entity list containing information about the people, places, things, mentions, present in the conversation\n", + "- TRIM: Trim messages in place ({user: ...} => {user: ...})\n", + "- SUMMARIZE: Combine two or more messages into one summary\n", + "- REMOVE: Safely remove messages from the session" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "6323b7b2-0aaf-4cea-896b-0c887054ce6e", + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "from pprint import pprint\n", + "import time\n", + "\n", + "def compactify(chat_session=chat_session):\n", + " start = time.time()\n", + " pprint(start)\n", + " \n", + " _sys_msg, *history_to_compact = get_leaf_nodes(chat_session=chat_session)\n", + "\n", + " history_to_compact = [\n", + " {\"index\": i+1, **msg} for i, msg in enumerate(history_to_compact)\n", + " ]\n", + " \n", + " system_prompt = f\"\"\"\\\n", + "You are given a session history of a chat between a user and a gpt-4-turbo language model created through the\n", + "openai api.\n", + "\n", + "Your goal is to compactify the history by removing or coalescing redundant or irrelevant information\n", + "in order to reduce its size and save costs. However, you must ensure that no important information is lost\n", + "that might be relevant in the future.\n", + "\n", + "\n", + "- You may remove entries in the history that do not contain any crucial information such as small-talk or repeated questions etc.\n", + "- You may combine multiple entries into a summary strictly as long as that doesn't disrupt the structure of the session.\n", + "- You may add a new entry describing the entities mentioned and then as a result, you may be able to remove other less relevant entries.\n", + "- You may add new entries if it helps you discard other less useful ones.\n", + "- You may convert an entry with some large content (such as an essay) into a list of points from the original content.\n", + "- Do not remove content that the user shared if it might be relevant to future messages.\n", + "\n", + "\n", + "\n", + "{json.dumps(example_chat, indent=2)}\n", + "\n", + "\n", + "\n", + "{example_chain_of_thought}\n", + "\n", + "\n", + "\n", + "{json.dumps(example_compacted_history, indent=2)}\n", + "\n", + "\"\"\".strip()\n", + "\n", + " user_message = f\"\"\"\\\n", + "\n", + "{json.dumps(history_to_compact, indent=2)}\n", + "\n", + "\n", + "\n", + "\"\"\"\n", + " messages = [system(system_prompt), user(user_message)]\n", + "\n", + " pprint(time.time() - start)\n", + " print(\"Starting CoT generation\")\n", + " cot_result = generate(messages, model=\"gpt-4-turbo\", stop=['\n", + "\"\"\".strip()\n", + "\n", + " messages.append(user(start_message))\n", + " \n", + " pprint(time.time() - start)\n", + " print(\"Starting chatml generation\")\n", + "\n", + " result = generate(messages, model=\"gpt-4-turbo\", temperature=0.1, stop=['=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphin test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] trio = ["trio (>=0.23)"] +[[package]] +name = "appnope" +version = "0.1.4" +description = "Disable App Nap on macOS >= 10.9" +optional = false +python-versions = ">=3.6" +files = [ + {file = "appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c"}, + {file = "appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee"}, +] + [[package]] name = "argcomplete" version = "3.3.0" @@ -157,6 +186,63 @@ files = [ [package.extras] test = ["coverage", "mypy", "pexpect", "ruff", "wheel"] +[[package]] +name = "argon2-cffi" +version = "23.1.0" +description = "Argon2 for Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "argon2_cffi-23.1.0-py3-none-any.whl", hash = "sha256:c670642b78ba29641818ab2e68bd4e6a78ba53b7eff7b4c3815ae16abf91c7ea"}, + {file = "argon2_cffi-23.1.0.tar.gz", hash = "sha256:879c3e79a2729ce768ebb7d36d4609e3a78a4ca2ec3a9f12286ca057e3d0db08"}, +] + +[package.dependencies] +argon2-cffi-bindings = "*" + +[package.extras] +dev = ["argon2-cffi[tests,typing]", "tox (>4)"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-copybutton", "sphinx-notfound-page"] +tests = ["hypothesis", "pytest"] +typing = ["mypy"] + +[[package]] +name = "argon2-cffi-bindings" +version = "21.2.0" +description = "Low-level CFFI bindings for Argon2" +optional = false +python-versions = ">=3.6" +files = [ + {file = "argon2-cffi-bindings-21.2.0.tar.gz", hash = "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9524464572e12979364b7d600abf96181d3541da11e23ddf565a32e70bd4dc0d"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b746dba803a79238e925d9046a63aa26bf86ab2a2fe74ce6b009a1c3f5c8f2ae"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58ed19212051f49a523abb1dbe954337dc82d947fb6e5a0da60f7c8471a8476c"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:bd46088725ef7f58b5a1ef7ca06647ebaf0eb4baff7d1d0d177c6cc8744abd86"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_i686.whl", hash = "sha256:8cd69c07dd875537a824deec19f978e0f2078fdda07fd5c42ac29668dda5f40f"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f1152ac548bd5b8bcecfb0b0371f082037e47128653df2e8ba6e914d384f3c3e"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-win32.whl", hash = "sha256:603ca0aba86b1349b147cab91ae970c63118a0f30444d4bc80355937c950c082"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-win_amd64.whl", hash = "sha256:b2ef1c30440dbbcba7a5dc3e319408b59676e2e039e2ae11a8775ecf482b192f"}, + {file = "argon2_cffi_bindings-21.2.0-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e415e3f62c8d124ee16018e491a009937f8cf7ebf5eb430ffc5de21b900dad93"}, + {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3e385d1c39c520c08b53d63300c3ecc28622f076f4c2b0e6d7e796e9f6502194"}, + {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c3e3cc67fdb7d82c4718f19b4e7a87123caf8a93fde7e23cf66ac0337d3cb3f"}, + {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a22ad9800121b71099d0fb0a65323810a15f2e292f2ba450810a7316e128ee5"}, + {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f9f8b450ed0547e3d473fdc8612083fd08dd2120d6ac8f73828df9b7d45bb351"}, + {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:93f9bf70084f97245ba10ee36575f0c3f1e7d7724d67d8e5b08e61787c320ed7"}, + {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3b9ef65804859d335dc6b31582cad2c5166f0c3e7975f324d9ffaa34ee7e6583"}, + {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4966ef5848d820776f5f562a7d45fdd70c2f330c961d0d745b784034bd9f48d"}, + {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20ef543a89dee4db46a1a6e206cd015360e5a75822f76df533845c3cbaf72670"}, + {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed2937d286e2ad0cc79a7087d3c272832865f779430e0cc2b4f3718d3159b0cb"}, + {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5e00316dabdaea0b2dd82d141cc66889ced0cdcbfa599e8b471cf22c620c329a"}, +] + +[package.dependencies] +cffi = ">=1.0.1" + +[package.extras] +dev = ["cogapp", "pre-commit", "pytest", "wheel"] +tests = ["pytest"] + [[package]] name = "arrow" version = "1.3.0" @@ -238,6 +324,20 @@ tests = ["attrs[tests-no-zope]", "zope-interface"] tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] +[[package]] +name = "babel" +version = "2.15.0" +description = "Internationalization utilities" +optional = false +python-versions = ">=3.8" +files = [ + {file = "Babel-2.15.0-py3-none-any.whl", hash = "sha256:08706bdad8d0a3413266ab61bd6c34d0c28d6e1e7badf40a2cebe67644e2e1fb"}, + {file = "babel-2.15.0.tar.gz", hash = "sha256:8daf0e265d05768bc6c7a314cf1321e9a123afc328cc635c18622a2f30a04413"}, +] + +[package.extras] +dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] + [[package]] name = "beartype" version = "0.18.5" @@ -256,6 +356,27 @@ doc-rtd = ["autoapi (>=0.9.0)", "pydata-sphinx-theme (<=0.7.2)", "sphinx (>=4.2. test-tox = ["equinox", "mypy (>=0.800)", "numpy", "pandera", "pytest (>=4.0.0)", "sphinx", "typing-extensions (>=3.10.0.0)"] test-tox-coverage = ["coverage (>=5.5)"] +[[package]] +name = "beautifulsoup4" +version = "4.12.3" +description = "Screen-scraping library" +optional = false +python-versions = ">=3.6.0" +files = [ + {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, + {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"}, +] + +[package.dependencies] +soupsieve = ">1.2" + +[package.extras] +cchardet = ["cchardet"] +chardet = ["chardet"] +charset-normalizer = ["charset-normalizer"] +html5lib = ["html5lib"] +lxml = ["lxml"] + [[package]] name = "black" version = "24.4.2" @@ -302,6 +423,24 @@ d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] +[[package]] +name = "bleach" +version = "6.1.0" +description = "An easy safelist-based HTML-sanitizing tool." +optional = false +python-versions = ">=3.8" +files = [ + {file = "bleach-6.1.0-py3-none-any.whl", hash = "sha256:3225f354cfc436b9789c66c4ee030194bee0568fbf9cbdad3bc8b5c26c5f12b6"}, + {file = "bleach-6.1.0.tar.gz", hash = "sha256:0a31f1837963c41d46bbf1331b8778e1308ea0791db03cc4e7357b97cf42a8fe"}, +] + +[package.dependencies] +six = ">=1.9.0" +webencodings = "*" + +[package.extras] +css = ["tinycss2 (>=1.1.0,<1.3)"] + [[package]] name = "cachetools" version = "5.3.3" @@ -324,6 +463,70 @@ files = [ {file = "certifi-2024.6.2.tar.gz", hash = "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516"}, ] +[[package]] +name = "cffi" +version = "1.16.0" +description = "Foreign Function Interface for Python calling C code." +optional = false +python-versions = ">=3.8" +files = [ + {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"}, + {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"}, + {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"}, + {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"}, + {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"}, + {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"}, + {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"}, + {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"}, + {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"}, + {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"}, + {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"}, + {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"}, + {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"}, + {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"}, + {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"}, + {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"}, + {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"}, + {file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"}, + {file = "cffi-1.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"}, + {file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"}, + {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"}, + {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"}, + {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"}, + {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"}, + {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"}, + {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"}, + {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"}, +] + +[package.dependencies] +pycparser = "*" + [[package]] name = "charset-normalizer" version = "3.3.2" @@ -470,6 +673,17 @@ click = "*" [package.extras] test = ["pytest"] +[[package]] +name = "cloudpickle" +version = "3.0.0" +description = "Pickler class to extend the standard pickle.Pickler functionality" +optional = false +python-versions = ">=3.8" +files = [ + {file = "cloudpickle-3.0.0-py3-none-any.whl", hash = "sha256:246ee7d0c295602a036e86369c77fecda4ab17b506496730f2f576d9016fd9c7"}, + {file = "cloudpickle-3.0.0.tar.gz", hash = "sha256:996d9a482c6fb4f33c1a35335cf8afd065d2a56e973270364840712d9131a882"}, +] + [[package]] name = "colorama" version = "0.4.6" @@ -481,6 +695,23 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "comm" +version = "0.2.2" +description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." +optional = false +python-versions = ">=3.8" +files = [ + {file = "comm-0.2.2-py3-none-any.whl", hash = "sha256:e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3"}, + {file = "comm-0.2.2.tar.gz", hash = "sha256:3fd7a84065306e07bea1773df6eb8282de51ba82f77c72f9c85716ab11fe980e"}, +] + +[package.dependencies] +traitlets = ">=4" + +[package.extras] +test = ["pytest"] + [[package]] name = "cozo-embedded" version = "0.7.6" @@ -529,6 +760,51 @@ files = [ [package.extras] develop = ["coverage", "invoke", "path.py", "pylint", "pytest (>=3.2)", "pytest-html (>=1.19.0)", "tox (>=2.9)"] +[[package]] +name = "dask" +version = "2024.5.2" +description = "Parallel PyData with Task Scheduling" +optional = false +python-versions = ">=3.9" +files = [ + {file = "dask-2024.5.2-py3-none-any.whl", hash = "sha256:acc2cfe41d9e0151c216ac40396dbe34df13bc3d8c51dfece190349e4f2243af"}, + {file = "dask-2024.5.2.tar.gz", hash = "sha256:5c9722c44d0195e78b6e54197aa3302e6fcaaac2310fd3014560bcb86253dcb3"}, +] + +[package.dependencies] +click = ">=8.1" +cloudpickle = ">=1.5.0" +distributed = {version = "2024.5.2", optional = true, markers = "extra == \"distributed\""} +fsspec = ">=2021.09.0" +importlib-metadata = {version = ">=4.13.0", markers = "python_version < \"3.12\""} +packaging = ">=20.0" +partd = ">=1.2.0" +pyyaml = ">=5.3.1" +toolz = ">=0.10.0" + +[package.extras] +array = ["numpy (>=1.21)"] +complete = ["dask[array,dataframe,diagnostics,distributed]", "lz4 (>=4.3.2)", "pyarrow (>=7.0)", "pyarrow-hotfix"] +dataframe = ["dask-expr (>=1.1,<1.2)", "dask[array]", "pandas (>=1.3)"] +diagnostics = ["bokeh (>=2.4.2)", "jinja2 (>=2.10.3)"] +distributed = ["distributed (==2024.5.2)"] +test = ["pandas[test]", "pre-commit", "pytest", "pytest-cov", "pytest-rerunfailures", "pytest-timeout", "pytest-xdist"] + +[[package]] +name = "dataclasses-json" +version = "0.6.6" +description = "Easily serialize dataclasses to and from JSON." +optional = false +python-versions = "<4.0,>=3.7" +files = [ + {file = "dataclasses_json-0.6.6-py3-none-any.whl", hash = "sha256:e54c5c87497741ad454070ba0ed411523d46beb5da102e221efb873801b0ba85"}, + {file = "dataclasses_json-0.6.6.tar.gz", hash = "sha256:0c09827d26fffda27f1be2fed7a7a01a29c5ddcd2eb6393ad5ebf9d77e9deae8"}, +] + +[package.dependencies] +marshmallow = ">=3.18.0,<4.0.0" +typing-inspect = ">=0.4.0,<1" + [[package]] name = "datamodel-code-generator" version = "0.25.6" @@ -558,6 +834,37 @@ graphql = ["graphql-core (>=3.2.3,<4.0.0)"] http = ["httpx"] validation = ["openapi-spec-validator (>=0.2.8,<0.7.0)", "prance (>=0.18.2)"] +[[package]] +name = "debugpy" +version = "1.8.1" +description = "An implementation of the Debug Adapter Protocol for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "debugpy-1.8.1-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:3bda0f1e943d386cc7a0e71bfa59f4137909e2ed947fb3946c506e113000f741"}, + {file = "debugpy-1.8.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dda73bf69ea479c8577a0448f8c707691152e6c4de7f0c4dec5a4bc11dee516e"}, + {file = "debugpy-1.8.1-cp310-cp310-win32.whl", hash = "sha256:3a79c6f62adef994b2dbe9fc2cc9cc3864a23575b6e387339ab739873bea53d0"}, + {file = "debugpy-1.8.1-cp310-cp310-win_amd64.whl", hash = "sha256:7eb7bd2b56ea3bedb009616d9e2f64aab8fc7000d481faec3cd26c98a964bcdd"}, + {file = "debugpy-1.8.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:016a9fcfc2c6b57f939673c874310d8581d51a0fe0858e7fac4e240c5eb743cb"}, + {file = "debugpy-1.8.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd97ed11a4c7f6d042d320ce03d83b20c3fb40da892f994bc041bbc415d7a099"}, + {file = "debugpy-1.8.1-cp311-cp311-win32.whl", hash = "sha256:0de56aba8249c28a300bdb0672a9b94785074eb82eb672db66c8144fff673146"}, + {file = "debugpy-1.8.1-cp311-cp311-win_amd64.whl", hash = "sha256:1a9fe0829c2b854757b4fd0a338d93bc17249a3bf69ecf765c61d4c522bb92a8"}, + {file = "debugpy-1.8.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3ebb70ba1a6524d19fa7bb122f44b74170c447d5746a503e36adc244a20ac539"}, + {file = "debugpy-1.8.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2e658a9630f27534e63922ebf655a6ab60c370f4d2fc5c02a5b19baf4410ace"}, + {file = "debugpy-1.8.1-cp312-cp312-win32.whl", hash = "sha256:caad2846e21188797a1f17fc09c31b84c7c3c23baf2516fed5b40b378515bbf0"}, + {file = "debugpy-1.8.1-cp312-cp312-win_amd64.whl", hash = "sha256:edcc9f58ec0fd121a25bc950d4578df47428d72e1a0d66c07403b04eb93bcf98"}, + {file = "debugpy-1.8.1-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:7a3afa222f6fd3d9dfecd52729bc2e12c93e22a7491405a0ecbf9e1d32d45b39"}, + {file = "debugpy-1.8.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d915a18f0597ef685e88bb35e5d7ab968964b7befefe1aaea1eb5b2640b586c7"}, + {file = "debugpy-1.8.1-cp38-cp38-win32.whl", hash = "sha256:92116039b5500633cc8d44ecc187abe2dfa9b90f7a82bbf81d079fcdd506bae9"}, + {file = "debugpy-1.8.1-cp38-cp38-win_amd64.whl", hash = "sha256:e38beb7992b5afd9d5244e96ad5fa9135e94993b0c551ceebf3fe1a5d9beb234"}, + {file = "debugpy-1.8.1-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:bfb20cb57486c8e4793d41996652e5a6a885b4d9175dd369045dad59eaacea42"}, + {file = "debugpy-1.8.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efd3fdd3f67a7e576dd869c184c5dd71d9aaa36ded271939da352880c012e703"}, + {file = "debugpy-1.8.1-cp39-cp39-win32.whl", hash = "sha256:58911e8521ca0c785ac7a0539f1e77e0ce2df753f786188f382229278b4cdf23"}, + {file = "debugpy-1.8.1-cp39-cp39-win_amd64.whl", hash = "sha256:6df9aa9599eb05ca179fb0b810282255202a66835c6efb1d112d21ecb830ddd3"}, + {file = "debugpy-1.8.1-py2.py3-none-any.whl", hash = "sha256:28acbe2241222b87e255260c76741e1fbf04fdc3b6d094fcf57b6c6f75ce1242"}, + {file = "debugpy-1.8.1.zip", hash = "sha256:f696d6be15be87aef621917585f9bb94b1dc9e8aced570db1b8a6fc14e8f9b42"}, +] + [[package]] name = "decorator" version = "5.1.1" @@ -569,6 +876,56 @@ files = [ {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, ] +[[package]] +name = "deepmerge" +version = "1.1.1" +description = "a toolset to deeply merge python dictionaries." +optional = false +python-versions = "*" +files = [ + {file = "deepmerge-1.1.1-py3-none-any.whl", hash = "sha256:7219dad9763f15be9dcd4bcb53e00f48e4eed6f5ed8f15824223eb934bb35977"}, + {file = "deepmerge-1.1.1.tar.gz", hash = "sha256:53a489dc9449636e480a784359ae2aab3191748c920649551c8e378622f0eca4"}, +] + +[[package]] +name = "defusedxml" +version = "0.7.1" +description = "XML bomb protection for Python stdlib modules" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, + {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, +] + +[[package]] +name = "distributed" +version = "2024.5.2" +description = "Distributed scheduler for Dask" +optional = false +python-versions = ">=3.9" +files = [ + {file = "distributed-2024.5.2-py3-none-any.whl", hash = "sha256:c0fd59d5c34179d9c9b5dc5acb42a00a06d163107b79f66c2dc73e9479a92286"}, + {file = "distributed-2024.5.2.tar.gz", hash = "sha256:4cee41093e98340d04d9254012c7d521065f64b3f33546dd0b02b00becb41e21"}, +] + +[package.dependencies] +click = ">=8.0" +cloudpickle = ">=1.5.0" +dask = "2024.5.2" +jinja2 = ">=2.10.3" +locket = ">=1.0.0" +msgpack = ">=1.0.0" +packaging = ">=20.0" +psutil = ">=5.7.2" +pyyaml = ">=5.3.1" +sortedcontainers = ">=2.0.5" +tblib = ">=1.6.0" +toolz = ">=0.10.0" +tornado = ">=6.0.4" +urllib3 = ">=1.24.3" +zict = ">=3.0.0" + [[package]] name = "distro" version = "1.9.0" @@ -675,6 +1032,44 @@ files = [ [package.extras] tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] +[[package]] +name = "faiss-cpu" +version = "1.8.0" +description = "A library for efficient similarity search and clustering of dense vectors." +optional = false +python-versions = ">=3.8" +files = [ + {file = "faiss-cpu-1.8.0.tar.gz", hash = "sha256:3ee1549491728f37b65267c192a94661a907154a8ae0546ad50a564b8be0d82e"}, + {file = "faiss_cpu-1.8.0-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:134a064c7411acf7d1d863173a9d2605c5a59bd573639ab39a5ded5ca983b1b2"}, + {file = "faiss_cpu-1.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ba8e6202d561ac57394c9d691ff17f8fa6eb9a077913a993fce0a154ec0176f1"}, + {file = "faiss_cpu-1.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a66e9fa7b70556a39681f06e0652f4124c8ddb0a1924afe4f0e40b6924dc845b"}, + {file = "faiss_cpu-1.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51aaef5a1255d0ea88ea7e52a2415f98c5dd2dd9cec10348d55136541eeec99f"}, + {file = "faiss_cpu-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:38152761242870ec7019e0397cbd0ed0b0716562029ce41a71bb38448bd6d5bc"}, + {file = "faiss_cpu-1.8.0-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:c9e6ad94b86626be1a0faff3e53c4ca169eba88aa156d7e90c5a2e9ba30558fb"}, + {file = "faiss_cpu-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4601dbd81733bf1bc3bff690aac981289fb386dc8e60d0c4eec8a37ba6856d20"}, + {file = "faiss_cpu-1.8.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa943d3b5e8c5c77cdd629d9c3c6f78d7da616e586fdd1b94aecbf2e5fa9ba06"}, + {file = "faiss_cpu-1.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b644b366c3b239b34fa3e08bf65bfc78a24eda1e1ea5b2b6d9be3e8fc73d8179"}, + {file = "faiss_cpu-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:f85ecf3514850f93985be238351f5a70736133cfae784b372640aa17c6343a1b"}, + {file = "faiss_cpu-1.8.0-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:61abc0129a357ac00f17f5167f14dff41480de2cc852f306c3d4cd36b893ccbd"}, + {file = "faiss_cpu-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b788186d6eb94e6333e1aa8bb6c84b66e967458ecdd1cee22e16f04c43ee674c"}, + {file = "faiss_cpu-1.8.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5658d90a202c62e4a69c5b065785e9ddcaf6986cb395c16afed8dbe4c58c31a2"}, + {file = "faiss_cpu-1.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d460a372efce547e53d3c47d2c2a8a90b186ad245969048c10c1d7a1e5cf21b"}, + {file = "faiss_cpu-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:9e6520324f0a6764dd267b3c32c76958bf2b1ec36752950f6fab31a7295980a0"}, + {file = "faiss_cpu-1.8.0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:fc44be179d5b7f690484ef0d0caf817fea2698a5275a0c7fb6cbf406e5b2e4d1"}, + {file = "faiss_cpu-1.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bbd6f0bc2e1424a12dc7e19d2cc95b53124867966b21110d26f909227e7ed1f1"}, + {file = "faiss_cpu-1.8.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06e7add0c8a06ce8fb0443c38fcaf49c45fb74527ea633b819e56452608e64f5"}, + {file = "faiss_cpu-1.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b864e23c1817fa6cfe9bbec096fd7140d596002934f71aa89b196ffb1b9cd846"}, + {file = "faiss_cpu-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:655433755845adbb6f0961e2f8980703640cb9faa96f1cd1ea190252149e0d0a"}, + {file = "faiss_cpu-1.8.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:e81fc376a3bcda213ffb395dda1018c953ce927c587731ad582f4e6c2b225363"}, + {file = "faiss_cpu-1.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8c6fa6b7eaf558307b4ab118a236e8d1da79a8685222928e4dd52e277dba144a"}, + {file = "faiss_cpu-1.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:652f6812ef2e8b0f9b18209828c590bc618aca82e7f1c1b1888f52928258e406"}, + {file = "faiss_cpu-1.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:304da4e0d19044374b63a5b6467028572eac4bd3f32bc9e8783d800a03fb1f02"}, + {file = "faiss_cpu-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:cb475d3f25f08c97ac64dfe026f113e2aeb9829b206b3b046256c3b40dd7eb62"}, +] + +[package.dependencies] +numpy = "*" + [[package]] name = "fastapi" version = "0.110.3" @@ -694,6 +1089,20 @@ typing-extensions = ">=4.8.0" [package.extras] all = ["email_validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] +[[package]] +name = "fastjsonschema" +version = "2.19.1" +description = "Fastest Python implementation of JSON schema" +optional = false +python-versions = "*" +files = [ + {file = "fastjsonschema-2.19.1-py3-none-any.whl", hash = "sha256:3672b47bc94178c9f23dbb654bf47440155d4db9df5f7bc47643315f9c405cd0"}, + {file = "fastjsonschema-2.19.1.tar.gz", hash = "sha256:e3126a94bdc4623d3de4485f8d468a12f02a67921315ddc87836d6e456dc789d"}, +] + +[package.extras] +devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benchmark", "pytest-cache", "validictory"] + [[package]] name = "filelock" version = "3.14.0" @@ -724,6 +1133,17 @@ files = [ six = "*" termcolor = "*" +[[package]] +name = "fqdn" +version = "1.5.1" +description = "Validates fully-qualified domain names against RFC 1123, so that they are acceptable to modern bowsers" +optional = false +python-versions = ">=2.7, !=3.0, !=3.1, !=3.2, !=3.3, !=3.4, <4" +files = [ + {file = "fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014"}, + {file = "fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f"}, +] + [[package]] name = "frozenlist" version = "1.4.1" @@ -812,13 +1232,13 @@ files = [ [[package]] name = "fsspec" -version = "2024.6.0" +version = "2024.5.0" description = "File-system specification" optional = false python-versions = ">=3.8" files = [ - {file = "fsspec-2024.6.0-py3-none-any.whl", hash = "sha256:58d7122eb8a1a46f7f13453187bfea4972d66bf01618d37366521b1998034cee"}, - {file = "fsspec-2024.6.0.tar.gz", hash = "sha256:f579960a56e6d8038a9efc8f9c77279ec12e6299aa86b0769a7e9c46b94527c2"}, + {file = "fsspec-2024.5.0-py3-none-any.whl", hash = "sha256:e0fdbc446d67e182f49a70b82cf7889028a63588fde6b222521f10937b2b670c"}, + {file = "fsspec-2024.5.0.tar.gz", hash = "sha256:1d021b0b0f933e3b3029ed808eb400c08ba101ca2de4b3483fbc9ca23fcee94a"}, ] [package.extras] @@ -827,7 +1247,6 @@ adl = ["adlfs"] arrow = ["pyarrow (>=1)"] dask = ["dask", "distributed"] dev = ["pre-commit", "ruff"] -doc = ["numpydoc", "sphinx", "sphinx-design", "sphinx-rtd-theme", "yarl"] dropbox = ["dropbox", "dropboxdrivefs", "requests"] full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "dask", "distributed", "dropbox", "dropboxdrivefs", "fusepy", "gcsfs", "libarchive-c", "ocifs", "panel", "paramiko", "pyarrow (>=1)", "pygit2", "requests", "s3fs", "smbprotocol", "tqdm"] fuse = ["fusepy"] @@ -957,13 +1376,13 @@ xai = ["tensorflow (>=2.3.0,<3.0.0dev)"] [[package]] name = "google-cloud-bigquery" -version = "3.24.0" +version = "3.23.1" description = "Google BigQuery API client library" optional = false python-versions = ">=3.7" files = [ - {file = "google-cloud-bigquery-3.24.0.tar.gz", hash = "sha256:e95e6f6e0aa32e6c453d44e2b3298931fdd7947c309ea329a31b6ff1f939e17e"}, - {file = "google_cloud_bigquery-3.24.0-py2.py3-none-any.whl", hash = "sha256:bc08323ce99dee4e811b7c3d0cde8929f5bf0b1aeaed6bcd75fc89796dd87652"}, + {file = "google-cloud-bigquery-3.23.1.tar.gz", hash = "sha256:4b4597f9291b42102c9667d3b4528f801d4c8f24ef2b12dd1ecb881273330955"}, + {file = "google_cloud_bigquery-3.23.1-py2.py3-none-any.whl", hash = "sha256:9fb72884fdbec9c4643cea6b7f21e1ecf3eb61d5305f87493d271dc801647a9e"}, ] [package.dependencies] @@ -1144,22 +1563,93 @@ requests = ["requests (>=2.18.0,<3.0.0dev)"] [[package]] name = "googleapis-common-protos" -version = "1.63.1" +version = "1.63.0" description = "Common protobufs used in Google APIs" optional = false python-versions = ">=3.7" files = [ - {file = "googleapis-common-protos-1.63.1.tar.gz", hash = "sha256:c6442f7a0a6b2a80369457d79e6672bb7dcbaab88e0848302497e3ec80780a6a"}, - {file = "googleapis_common_protos-1.63.1-py2.py3-none-any.whl", hash = "sha256:0e1c2cdfcbc354b76e4a211a35ea35d6926a835cba1377073c4861db904a1877"}, + {file = "googleapis-common-protos-1.63.0.tar.gz", hash = "sha256:17ad01b11d5f1d0171c06d3ba5c04c54474e883b66b949722b4938ee2694ef4e"}, + {file = "googleapis_common_protos-1.63.0-py2.py3-none-any.whl", hash = "sha256:ae45f75702f7c08b541f750854a678bd8f534a1a6bace6afe975f1d0a82d6632"}, ] [package.dependencies] grpcio = {version = ">=1.44.0,<2.0.0.dev0", optional = true, markers = "extra == \"grpc\""} -protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<6.0.0.dev0" +protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0.dev0" [package.extras] grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"] +[[package]] +name = "greenlet" +version = "3.0.3" +description = "Lightweight in-process concurrent programming" +optional = false +python-versions = ">=3.7" +files = [ + {file = "greenlet-3.0.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:9da2bd29ed9e4f15955dd1595ad7bc9320308a3b766ef7f837e23ad4b4aac31a"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d353cadd6083fdb056bb46ed07e4340b0869c305c8ca54ef9da3421acbdf6881"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dca1e2f3ca00b84a396bc1bce13dd21f680f035314d2379c4160c98153b2059b"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ed7fb269f15dc662787f4119ec300ad0702fa1b19d2135a37c2c4de6fadfd4a"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd4f49ae60e10adbc94b45c0b5e6a179acc1736cf7a90160b404076ee283cf83"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:73a411ef564e0e097dbe7e866bb2dda0f027e072b04da387282b02c308807405"}, + {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7f362975f2d179f9e26928c5b517524e89dd48530a0202570d55ad6ca5d8a56f"}, + {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:649dde7de1a5eceb258f9cb00bdf50e978c9db1b996964cd80703614c86495eb"}, + {file = "greenlet-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:68834da854554926fbedd38c76e60c4a2e3198c6fbed520b106a8986445caaf9"}, + {file = "greenlet-3.0.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:b1b5667cced97081bf57b8fa1d6bfca67814b0afd38208d52538316e9422fc61"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52f59dd9c96ad2fc0d5724107444f76eb20aaccb675bf825df6435acb7703559"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:afaff6cf5200befd5cec055b07d1c0a5a06c040fe5ad148abcd11ba6ab9b114e"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2797aa5aedac23af156bbb5a6aa2cd3427ada2972c828244eb7d1b9255846379"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7f009caad047246ed379e1c4dbcb8b020f0a390667ea74d2387be2998f58a22"}, + {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c5e1536de2aad7bf62e27baf79225d0d64360d4168cf2e6becb91baf1ed074f3"}, + {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:894393ce10ceac937e56ec00bb71c4c2f8209ad516e96033e4b3b1de270e200d"}, + {file = "greenlet-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:1ea188d4f49089fc6fb283845ab18a2518d279c7cd9da1065d7a84e991748728"}, + {file = "greenlet-3.0.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf"}, + {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305"}, + {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6"}, + {file = "greenlet-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2"}, + {file = "greenlet-3.0.3-cp37-cp37m-macosx_11_0_universal2.whl", hash = "sha256:5b51e85cb5ceda94e79d019ed36b35386e8c37d22f07d6a751cb659b180d5274"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:daf3cb43b7cf2ba96d614252ce1684c1bccee6b2183a01328c98d36fcd7d5cb0"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99bf650dc5d69546e076f413a87481ee1d2d09aaaaaca058c9251b6d8c14783f"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dd6e660effd852586b6a8478a1d244b8dc90ab5b1321751d2ea15deb49ed414"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3391d1e16e2a5a1507d83e4a8b100f4ee626e8eca43cf2cadb543de69827c4c"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1f145462f1fa6e4a4ae3c0f782e580ce44d57c8f2c7aae1b6fa88c0b2efdb41"}, + {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1a7191e42732df52cb5f39d3527217e7ab73cae2cb3694d241e18f53d84ea9a7"}, + {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0448abc479fab28b00cb472d278828b3ccca164531daab4e970a0458786055d6"}, + {file = "greenlet-3.0.3-cp37-cp37m-win32.whl", hash = "sha256:b542be2440edc2d48547b5923c408cbe0fc94afb9f18741faa6ae970dbcb9b6d"}, + {file = "greenlet-3.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67"}, + {file = "greenlet-3.0.3-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:1996cb9306c8595335bb157d133daf5cf9f693ef413e7673cb07e3e5871379ca"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ddc0f794e6ad661e321caa8d2f0a55ce01213c74722587256fb6566049a8b04"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9db1c18f0eaad2f804728c67d6c610778456e3e1cc4ab4bbd5eeb8e6053c6fc"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7170375bcc99f1a2fbd9c306f5be8764eaf3ac6b5cb968862cad4c7057756506"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b66c9c1e7ccabad3a7d037b2bcb740122a7b17a53734b7d72a344ce39882a1b"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:098d86f528c855ead3479afe84b49242e174ed262456c342d70fc7f972bc13c4"}, + {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:81bb9c6d52e8321f09c3d165b2a78c680506d9af285bfccbad9fb7ad5a5da3e5"}, + {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da"}, + {file = "greenlet-3.0.3-cp38-cp38-win32.whl", hash = "sha256:d46677c85c5ba00a9cb6f7a00b2bfa6f812192d2c9f7d9c4f6a55b60216712f3"}, + {file = "greenlet-3.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:419b386f84949bf0e7c73e6032e3457b82a787c1ab4a0e43732898a761cc9dbf"}, + {file = "greenlet-3.0.3-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:da70d4d51c8b306bb7a031d5cff6cc25ad253affe89b70352af5f1cb68e74b53"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086152f8fbc5955df88382e8a75984e2bb1c892ad2e3c80a2508954e52295257"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d73a9fe764d77f87f8ec26a0c85144d6a951a6c438dfe50487df5595c6373eac"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7dcbe92cc99f08c8dd11f930de4d99ef756c3591a5377d1d9cd7dd5e896da71"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1551a8195c0d4a68fac7a4325efac0d541b48def35feb49d803674ac32582f61"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:64d7675ad83578e3fc149b617a444fab8efdafc9385471f868eb5ff83e446b8b"}, + {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b37eef18ea55f2ffd8f00ff8fe7c8d3818abd3e25fb73fae2ca3b672e333a7a6"}, + {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:77457465d89b8263bca14759d7c1684df840b6811b2499838cc5b040a8b5b113"}, + {file = "greenlet-3.0.3-cp39-cp39-win32.whl", hash = "sha256:57e8974f23e47dac22b83436bdcf23080ade568ce77df33159e019d161ce1d1e"}, + {file = "greenlet-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:c5ee858cfe08f34712f548c3c363e807e7186f03ad7a5039ebadb29e8c6be067"}, + {file = "greenlet-3.0.3.tar.gz", hash = "sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491"}, +] + +[package.extras] +docs = ["Sphinx", "furo"] +test = ["objgraph", "psutil"] + [[package]] name = "grpc-google-iam-v1" version = "0.13.0" @@ -1178,61 +1668,61 @@ protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.1 || >4.21.1,<4 [[package]] name = "grpcio" -version = "1.64.1" +version = "1.64.0" description = "HTTP/2-based RPC framework" optional = false python-versions = ">=3.8" files = [ - {file = "grpcio-1.64.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:55697ecec192bc3f2f3cc13a295ab670f51de29884ca9ae6cd6247df55df2502"}, - {file = "grpcio-1.64.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:3b64ae304c175671efdaa7ec9ae2cc36996b681eb63ca39c464958396697daff"}, - {file = "grpcio-1.64.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:bac71b4b28bc9af61efcdc7630b166440bbfbaa80940c9a697271b5e1dabbc61"}, - {file = "grpcio-1.64.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c024ffc22d6dc59000faf8ad781696d81e8e38f4078cb0f2630b4a3cf231a90"}, - {file = "grpcio-1.64.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7cd5c1325f6808b8ae31657d281aadb2a51ac11ab081ae335f4f7fc44c1721d"}, - {file = "grpcio-1.64.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0a2813093ddb27418a4c99f9b1c223fab0b053157176a64cc9db0f4557b69bd9"}, - {file = "grpcio-1.64.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2981c7365a9353f9b5c864595c510c983251b1ab403e05b1ccc70a3d9541a73b"}, - {file = "grpcio-1.64.1-cp310-cp310-win32.whl", hash = "sha256:1262402af5a511c245c3ae918167eca57342c72320dffae5d9b51840c4b2f86d"}, - {file = "grpcio-1.64.1-cp310-cp310-win_amd64.whl", hash = "sha256:19264fc964576ddb065368cae953f8d0514ecc6cb3da8903766d9fb9d4554c33"}, - {file = "grpcio-1.64.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:58b1041e7c870bb30ee41d3090cbd6f0851f30ae4eb68228955d973d3efa2e61"}, - {file = "grpcio-1.64.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bbc5b1d78a7822b0a84c6f8917faa986c1a744e65d762ef6d8be9d75677af2ca"}, - {file = "grpcio-1.64.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:5841dd1f284bd1b3d8a6eca3a7f062b06f1eec09b184397e1d1d43447e89a7ae"}, - {file = "grpcio-1.64.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8caee47e970b92b3dd948371230fcceb80d3f2277b3bf7fbd7c0564e7d39068e"}, - {file = "grpcio-1.64.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:73819689c169417a4f978e562d24f2def2be75739c4bed1992435d007819da1b"}, - {file = "grpcio-1.64.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6503b64c8b2dfad299749cad1b595c650c91e5b2c8a1b775380fcf8d2cbba1e9"}, - {file = "grpcio-1.64.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1de403fc1305fd96cfa75e83be3dee8538f2413a6b1685b8452301c7ba33c294"}, - {file = "grpcio-1.64.1-cp311-cp311-win32.whl", hash = "sha256:d4d29cc612e1332237877dfa7fe687157973aab1d63bd0f84cf06692f04c0367"}, - {file = "grpcio-1.64.1-cp311-cp311-win_amd64.whl", hash = "sha256:5e56462b05a6f860b72f0fa50dca06d5b26543a4e88d0396259a07dc30f4e5aa"}, - {file = "grpcio-1.64.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:4657d24c8063e6095f850b68f2d1ba3b39f2b287a38242dcabc166453e950c59"}, - {file = "grpcio-1.64.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:62b4e6eb7bf901719fce0ca83e3ed474ae5022bb3827b0a501e056458c51c0a1"}, - {file = "grpcio-1.64.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:ee73a2f5ca4ba44fa33b4d7d2c71e2c8a9e9f78d53f6507ad68e7d2ad5f64a22"}, - {file = "grpcio-1.64.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:198908f9b22e2672a998870355e226a725aeab327ac4e6ff3a1399792ece4762"}, - {file = "grpcio-1.64.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39b9d0acaa8d835a6566c640f48b50054f422d03e77e49716d4c4e8e279665a1"}, - {file = "grpcio-1.64.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:5e42634a989c3aa6049f132266faf6b949ec2a6f7d302dbb5c15395b77d757eb"}, - {file = "grpcio-1.64.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b1a82e0b9b3022799c336e1fc0f6210adc019ae84efb7321d668129d28ee1efb"}, - {file = "grpcio-1.64.1-cp312-cp312-win32.whl", hash = "sha256:55260032b95c49bee69a423c2f5365baa9369d2f7d233e933564d8a47b893027"}, - {file = "grpcio-1.64.1-cp312-cp312-win_amd64.whl", hash = "sha256:c1a786ac592b47573a5bb7e35665c08064a5d77ab88a076eec11f8ae86b3e3f6"}, - {file = "grpcio-1.64.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:a011ac6c03cfe162ff2b727bcb530567826cec85eb8d4ad2bfb4bd023287a52d"}, - {file = "grpcio-1.64.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:4d6dab6124225496010bd22690f2d9bd35c7cbb267b3f14e7a3eb05c911325d4"}, - {file = "grpcio-1.64.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:a5e771d0252e871ce194d0fdcafd13971f1aae0ddacc5f25615030d5df55c3a2"}, - {file = "grpcio-1.64.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2c3c1b90ab93fed424e454e93c0ed0b9d552bdf1b0929712b094f5ecfe7a23ad"}, - {file = "grpcio-1.64.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20405cb8b13fd779135df23fabadc53b86522d0f1cba8cca0e87968587f50650"}, - {file = "grpcio-1.64.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:0cc79c982ccb2feec8aad0e8fb0d168bcbca85bc77b080d0d3c5f2f15c24ea8f"}, - {file = "grpcio-1.64.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a3a035c37ce7565b8f4f35ff683a4db34d24e53dc487e47438e434eb3f701b2a"}, - {file = "grpcio-1.64.1-cp38-cp38-win32.whl", hash = "sha256:1257b76748612aca0f89beec7fa0615727fd6f2a1ad580a9638816a4b2eb18fd"}, - {file = "grpcio-1.64.1-cp38-cp38-win_amd64.whl", hash = "sha256:0a12ddb1678ebc6a84ec6b0487feac020ee2b1659cbe69b80f06dbffdb249122"}, - {file = "grpcio-1.64.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:75dbbf415026d2862192fe1b28d71f209e2fd87079d98470db90bebe57b33179"}, - {file = "grpcio-1.64.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e3d9f8d1221baa0ced7ec7322a981e28deb23749c76eeeb3d33e18b72935ab62"}, - {file = "grpcio-1.64.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:5f8b75f64d5d324c565b263c67dbe4f0af595635bbdd93bb1a88189fc62ed2e5"}, - {file = "grpcio-1.64.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c84ad903d0d94311a2b7eea608da163dace97c5fe9412ea311e72c3684925602"}, - {file = "grpcio-1.64.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:940e3ec884520155f68a3b712d045e077d61c520a195d1a5932c531f11883489"}, - {file = "grpcio-1.64.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f10193c69fc9d3d726e83bbf0f3d316f1847c3071c8c93d8090cf5f326b14309"}, - {file = "grpcio-1.64.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ac15b6c2c80a4d1338b04d42a02d376a53395ddf0ec9ab157cbaf44191f3ffdd"}, - {file = "grpcio-1.64.1-cp39-cp39-win32.whl", hash = "sha256:03b43d0ccf99c557ec671c7dede64f023c7da9bb632ac65dbc57f166e4970040"}, - {file = "grpcio-1.64.1-cp39-cp39-win_amd64.whl", hash = "sha256:ed6091fa0adcc7e4ff944090cf203a52da35c37a130efa564ded02b7aff63bcd"}, - {file = "grpcio-1.64.1.tar.gz", hash = "sha256:8d51dd1c59d5fa0f34266b80a3805ec29a1f26425c2a54736133f6d87fc4968a"}, -] - -[package.extras] -protobuf = ["grpcio-tools (>=1.64.1)"] + {file = "grpcio-1.64.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:3b09c3d9de95461214a11d82cc0e6a46a6f4e1f91834b50782f932895215e5db"}, + {file = "grpcio-1.64.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:7e013428ab472892830287dd082b7d129f4d8afef49227a28223a77337555eaa"}, + {file = "grpcio-1.64.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:02cc9cc3f816d30f7993d0d408043b4a7d6a02346d251694d8ab1f78cc723e7e"}, + {file = "grpcio-1.64.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f5de082d936e0208ce8db9095821361dfa97af8767a6607ae71425ac8ace15c"}, + {file = "grpcio-1.64.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7b7bf346391dffa182fba42506adf3a84f4a718a05e445b37824136047686a1"}, + {file = "grpcio-1.64.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b2cbdfba18408389a1371f8c2af1659119e1831e5ed24c240cae9e27b4abc38d"}, + {file = "grpcio-1.64.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:aca4f15427d2df592e0c8f3d38847e25135e4092d7f70f02452c0e90d6a02d6d"}, + {file = "grpcio-1.64.0-cp310-cp310-win32.whl", hash = "sha256:7c1f5b2298244472bcda49b599be04579f26425af0fd80d3f2eb5fd8bc84d106"}, + {file = "grpcio-1.64.0-cp310-cp310-win_amd64.whl", hash = "sha256:73f84f9e5985a532e47880b3924867de16fa1aa513fff9b26106220c253c70c5"}, + {file = "grpcio-1.64.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:2a18090371d138a57714ee9bffd6c9c9cb2e02ce42c681aac093ae1e7189ed21"}, + {file = "grpcio-1.64.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:59c68df3a934a586c3473d15956d23a618b8f05b5e7a3a904d40300e9c69cbf0"}, + {file = "grpcio-1.64.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:b52e1ec7185512103dd47d41cf34ea78e7a7361ba460187ddd2416b480e0938c"}, + {file = "grpcio-1.64.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8d598b5d5e2c9115d7fb7e2cb5508d14286af506a75950762aa1372d60e41851"}, + {file = "grpcio-1.64.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01615bbcae6875eee8091e6b9414072f4e4b00d8b7e141f89635bdae7cf784e5"}, + {file = "grpcio-1.64.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0b2dfe6dcace264807d9123d483d4c43274e3f8c39f90ff51de538245d7a4145"}, + {file = "grpcio-1.64.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7f17572dc9acd5e6dfd3014d10c0b533e9f79cd9517fc10b0225746f4c24b58e"}, + {file = "grpcio-1.64.0-cp311-cp311-win32.whl", hash = "sha256:6ec5ed15b4ffe56e2c6bc76af45e6b591c9be0224b3fb090adfb205c9012367d"}, + {file = "grpcio-1.64.0-cp311-cp311-win_amd64.whl", hash = "sha256:597191370951b477b7a1441e1aaa5cacebeb46a3b0bd240ec3bb2f28298c7553"}, + {file = "grpcio-1.64.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:1ce4cd5a61d4532651079e7aae0fedf9a80e613eed895d5b9743e66b52d15812"}, + {file = "grpcio-1.64.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:650a8150a9b288f40d5b7c1d5400cc11724eae50bd1f501a66e1ea949173649b"}, + {file = "grpcio-1.64.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:8de0399b983f8676a7ccfdd45e5b2caec74a7e3cc576c6b1eecf3b3680deda5e"}, + {file = "grpcio-1.64.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:46b8b43ba6a2a8f3103f103f97996cad507bcfd72359af6516363c48793d5a7b"}, + {file = "grpcio-1.64.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a54362f03d4dcfae63be455d0a7d4c1403673498b92c6bfe22157d935b57c7a9"}, + {file = "grpcio-1.64.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1f8ea18b928e539046bb5f9c124d717fbf00cc4b2d960ae0b8468562846f5aa1"}, + {file = "grpcio-1.64.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c56c91bd2923ddb6e7ed28ebb66d15633b03e0df22206f22dfcdde08047e0a48"}, + {file = "grpcio-1.64.0-cp312-cp312-win32.whl", hash = "sha256:874c741c8a66f0834f653a69e7e64b4e67fcd4a8d40296919b93bab2ccc780ba"}, + {file = "grpcio-1.64.0-cp312-cp312-win_amd64.whl", hash = "sha256:0da1d921f8e4bcee307aeef6c7095eb26e617c471f8cb1c454fd389c5c296d1e"}, + {file = "grpcio-1.64.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:c46fb6bfca17bfc49f011eb53416e61472fa96caa0979b4329176bdd38cbbf2a"}, + {file = "grpcio-1.64.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3d2004e85cf5213995d09408501f82c8534700d2babeb81dfdba2a3bff0bb396"}, + {file = "grpcio-1.64.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:6d5541eb460d73a07418524fb64dcfe0adfbcd32e2dac0f8f90ce5b9dd6c046c"}, + {file = "grpcio-1.64.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f279ad72dd7d64412e10f2443f9f34872a938c67387863c4cd2fb837f53e7d2"}, + {file = "grpcio-1.64.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85fda90b81da25993aa47fae66cae747b921f8f6777550895fb62375b776a231"}, + {file = "grpcio-1.64.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a053584079b793a54bece4a7d1d1b5c0645bdbee729215cd433703dc2532f72b"}, + {file = "grpcio-1.64.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:579dd9fb11bc73f0de061cab5f8b2def21480fd99eb3743ed041ad6a1913ee2f"}, + {file = "grpcio-1.64.0-cp38-cp38-win32.whl", hash = "sha256:23b6887bb21d77649d022fa1859e05853fdc2e60682fd86c3db652a555a282e0"}, + {file = "grpcio-1.64.0-cp38-cp38-win_amd64.whl", hash = "sha256:753cb58683ba0c545306f4e17dabf468d29cb6f6b11832e1e432160bb3f8403c"}, + {file = "grpcio-1.64.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:2186d76a7e383e1466e0ea2b0febc343ffeae13928c63c6ec6826533c2d69590"}, + {file = "grpcio-1.64.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0f30596cdcbed3c98024fb4f1d91745146385b3f9fd10c9f2270cbfe2ed7ed91"}, + {file = "grpcio-1.64.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:d9171f025a196f5bcfec7e8e7ffb7c3535f7d60aecd3503f9e250296c7cfc150"}, + {file = "grpcio-1.64.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf4c8daed18ae2be2f1fc7d613a76ee2a2e28fdf2412d5c128be23144d28283d"}, + {file = "grpcio-1.64.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3550493ac1d23198d46dc9c9b24b411cef613798dc31160c7138568ec26bc9b4"}, + {file = "grpcio-1.64.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:3161a8f8bb38077a6470508c1a7301cd54301c53b8a34bb83e3c9764874ecabd"}, + {file = "grpcio-1.64.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2e8fabe2cc57a369638ab1ad8e6043721014fdf9a13baa7c0e35995d3a4a7618"}, + {file = "grpcio-1.64.0-cp39-cp39-win32.whl", hash = "sha256:31890b24d47b62cc27da49a462efe3d02f3c120edb0e6c46dcc0025506acf004"}, + {file = "grpcio-1.64.0-cp39-cp39-win_amd64.whl", hash = "sha256:5a56797dea8c02e7d3a85dfea879f286175cf4d14fbd9ab3ef2477277b927baa"}, + {file = "grpcio-1.64.0.tar.gz", hash = "sha256:257baf07f53a571c215eebe9679c3058a313fd1d1f7c4eede5a8660108c52d9c"}, +] + +[package.extras] +protobuf = ["grpcio-tools (>=1.64.0)"] [[package]] name = "grpcio-status" @@ -1308,13 +1798,13 @@ socks = ["socksio (==1.*)"] [[package]] name = "huggingface-hub" -version = "0.23.3" +version = "0.23.2" description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub" optional = false python-versions = ">=3.8.0" files = [ - {file = "huggingface_hub-0.23.3-py3-none-any.whl", hash = "sha256:22222c41223f1b7c209ae5511d2d82907325a0e3cdbce5f66949d43c598ff3bc"}, - {file = "huggingface_hub-0.23.3.tar.gz", hash = "sha256:1a1118a0b3dea3bab6c325d71be16f5ffe441d32f3ac7c348d6875911b694b5b"}, + {file = "huggingface_hub-0.23.2-py3-none-any.whl", hash = "sha256:48727a16e704d409c4bb5913613308499664f22a99743435dc3a13b23c485827"}, + {file = "huggingface_hub-0.23.2.tar.gz", hash = "sha256:f6829b62d5fdecb452a76fdbec620cba4c1573655a8d710c1df71735fd9edbd2"}, ] [package.dependencies] @@ -1410,6 +1900,39 @@ files = [ docs = ["jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx"] testing = ["pygments", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +[[package]] +name = "ipykernel" +version = "6.29.4" +description = "IPython Kernel for Jupyter" +optional = false +python-versions = ">=3.8" +files = [ + {file = "ipykernel-6.29.4-py3-none-any.whl", hash = "sha256:1181e653d95c6808039c509ef8e67c4126b3b3af7781496c7cbfb5ed938a27da"}, + {file = "ipykernel-6.29.4.tar.gz", hash = "sha256:3d44070060f9475ac2092b760123fadf105d2e2493c24848b6691a7c4f42af5c"}, +] + +[package.dependencies] +appnope = {version = "*", markers = "platform_system == \"Darwin\""} +comm = ">=0.1.1" +debugpy = ">=1.6.5" +ipython = ">=7.23.1" +jupyter-client = ">=6.1.12" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +matplotlib-inline = ">=0.1" +nest-asyncio = "*" +packaging = "*" +psutil = "*" +pyzmq = ">=24" +tornado = ">=6.1" +traitlets = ">=5.4.0" + +[package.extras] +cov = ["coverage[toml]", "curio", "matplotlib", "pytest-cov", "trio"] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "trio"] +pyqt5 = ["pyqt5"] +pyside6 = ["pyside6"] +test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.23.5)", "pytest-cov", "pytest-timeout"] + [[package]] name = "ipython" version = "8.25.0" @@ -1448,6 +1971,41 @@ qtconsole = ["qtconsole"] test = ["pickleshare", "pytest", "pytest-asyncio (<0.22)", "testpath"] test-extra = ["curio", "ipython[test]", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.23)", "pandas", "trio"] +[[package]] +name = "ipywidgets" +version = "8.1.3" +description = "Jupyter interactive widgets" +optional = false +python-versions = ">=3.7" +files = [ + {file = "ipywidgets-8.1.3-py3-none-any.whl", hash = "sha256:efafd18f7a142248f7cb0ba890a68b96abd4d6e88ddbda483c9130d12667eaf2"}, + {file = "ipywidgets-8.1.3.tar.gz", hash = "sha256:f5f9eeaae082b1823ce9eac2575272952f40d748893972956dc09700a6392d9c"}, +] + +[package.dependencies] +comm = ">=0.1.3" +ipython = ">=6.1.0" +jupyterlab-widgets = ">=3.0.11,<3.1.0" +traitlets = ">=4.3.1" +widgetsnbextension = ">=4.0.11,<4.1.0" + +[package.extras] +test = ["ipykernel", "jsonschema", "pytest (>=3.6.0)", "pytest-cov", "pytz"] + +[[package]] +name = "isoduration" +version = "20.11.0" +description = "Operations with ISO 8601 durations" +optional = false +python-versions = ">=3.7" +files = [ + {file = "isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042"}, + {file = "isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9"}, +] + +[package.dependencies] +arrow = ">=0.15.0" + [[package]] name = "isort" version = "5.13.2" @@ -1511,6 +2069,56 @@ files = [ [package.dependencies] Jinja2 = ">=2.2" +[[package]] +name = "json5" +version = "0.9.25" +description = "A Python implementation of the JSON5 data format." +optional = false +python-versions = ">=3.8" +files = [ + {file = "json5-0.9.25-py3-none-any.whl", hash = "sha256:34ed7d834b1341a86987ed52f3f76cd8ee184394906b6e22a1e0deb9ab294e8f"}, + {file = "json5-0.9.25.tar.gz", hash = "sha256:548e41b9be043f9426776f05df8635a00fe06104ea51ed24b67f908856e151ae"}, +] + +[[package]] +name = "jsonpatch" +version = "1.33" +description = "Apply JSON-Patches (RFC 6902)" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" +files = [ + {file = "jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade"}, + {file = "jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c"}, +] + +[package.dependencies] +jsonpointer = ">=1.9" + +[[package]] +name = "jsonpath-ng" +version = "1.6.1" +description = "A final implementation of JSONPath for Python that aims to be standard compliant, including arithmetic and binary comparison operators and providing clear AST for metaprogramming." +optional = false +python-versions = "*" +files = [ + {file = "jsonpath-ng-1.6.1.tar.gz", hash = "sha256:086c37ba4917304850bd837aeab806670224d3f038fe2833ff593a672ef0a5fa"}, + {file = "jsonpath_ng-1.6.1-py3-none-any.whl", hash = "sha256:8f22cd8273d7772eea9aaa84d922e0841aa36fdb8a2c6b7f6c3791a16a9bc0be"}, +] + +[package.dependencies] +ply = "*" + +[[package]] +name = "jsonpointer" +version = "2.4" +description = "Identify specific nodes in a JSON document (RFC 6901)" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" +files = [ + {file = "jsonpointer-2.4-py2.py3-none-any.whl", hash = "sha256:15d51bba20eea3165644553647711d150376234112651b4f1811022aecad7d7a"}, + {file = "jsonpointer-2.4.tar.gz", hash = "sha256:585cee82b70211fa9e6043b7bb89db6e1aa49524340dde8ad6b63206ea689d88"}, +] + [[package]] name = "jsonschema" version = "4.22.0" @@ -1524,9 +2132,17 @@ files = [ [package.dependencies] attrs = ">=22.2.0" +fqdn = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +idna = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +isoduration = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +jsonpointer = {version = ">1.13", optional = true, markers = "extra == \"format-nongpl\""} jsonschema-specifications = ">=2023.03.6" referencing = ">=0.28.4" +rfc3339-validator = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +rfc3986-validator = {version = ">0.1.0", optional = true, markers = "extra == \"format-nongpl\""} rpds-py = ">=0.7.1" +uri-template = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +webcolors = {version = ">=1.11", optional = true, markers = "extra == \"format-nongpl\""} [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] @@ -1565,6 +2181,411 @@ openai = ">=1.0.1,<2.0.0" pydantic = ">=2.0.1,<3.0.0" typing-extensions = ">=4.0.0,<5.0.0" +[[package]] +name = "jupyter-ai" +version = "2.16.0" +description = "A generative AI extension for JupyterLab" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter_ai-2.16.0-py3-none-any.whl", hash = "sha256:7f428a4a01c050bfa0722dd81688e43416ff1e5b15339f00e8efa544fd0b7fc9"}, + {file = "jupyter_ai-2.16.0.tar.gz", hash = "sha256:6fb78ee82ea6c0174f26142615d427a038f19ed1fc16a5779dc81715f8d2a5b1"}, +] + +[package.dependencies] +aiosqlite = ">=0.18" +dask = {version = "*", extras = ["distributed"]} +deepmerge = ">=1.0" +faiss-cpu = "*" +importlib-metadata = ">=5.2.0" +jupyter-ai-magics = ">=2.13.0" +jupyter-server = ">=1.6,<3" +jupyterlab = ">=4.0,<5.0" +traitlets = ">=5.0" +typing-extensions = ">=4.5.0" + +[package.extras] +all = ["arxiv", "jupyter-ai-magics[all]", "pypdf"] +dev = ["jupyter-ai-magics[dev]"] +test = ["coverage", "jupyter-server[test] (>=1.6,<3)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-jupyter", "pytest-tornasync", "syrupy (>=4.0.8,<4.1.0)"] + +[[package]] +name = "jupyter-ai-magics" +version = "2.16.0" +description = "Jupyter AI magics Python package. Not published on NPM." +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter_ai_magics-2.16.0-py3-none-any.whl", hash = "sha256:9c231a12350ca5c8a3db2ea8dae0517bc046bb7d2351b66a26e3ede946edf895"}, + {file = "jupyter_ai_magics-2.16.0.tar.gz", hash = "sha256:f35cce92814ccf63ac2b900275f7470f459e4857376a3575c4c25f13707923da"}, +] + +[package.dependencies] +click = ">=8.0,<9.0" +importlib-metadata = ">=5.2.0" +ipython = "*" +jsonpath-ng = ">=1.5.3,<2" +langchain = ">=0.1.0,<0.2.0" +typing-extensions = ">=4.5.0" + +[package.extras] +all = ["ai21", "boto3", "cohere (>4.40,<5)", "gpt4all", "huggingface-hub", "ipywidgets", "langchain-anthropic", "langchain-google-genai", "langchain-nvidia-ai-endpoints", "langchain-openai", "pillow", "qianfan", "together"] +dev = ["pre-commit (>=3.3.3,<4)"] +test = ["coverage", "pytest", "pytest-asyncio", "pytest-cov"] + +[[package]] +name = "jupyter-client" +version = "8.6.2" +description = "Jupyter protocol implementation and client libraries" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter_client-8.6.2-py3-none-any.whl", hash = "sha256:50cbc5c66fd1b8f65ecb66bc490ab73217993632809b6e505687de18e9dea39f"}, + {file = "jupyter_client-8.6.2.tar.gz", hash = "sha256:2bda14d55ee5ba58552a8c53ae43d215ad9868853489213f37da060ced54d8df"}, +] + +[package.dependencies] +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +python-dateutil = ">=2.8.2" +pyzmq = ">=23.0" +tornado = ">=6.2" +traitlets = ">=5.3" + +[package.extras] +docs = ["ipykernel", "myst-parser", "pydata-sphinx-theme", "sphinx (>=4)", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] +test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pytest (<8.2.0)", "pytest-cov", "pytest-jupyter[client] (>=0.4.1)", "pytest-timeout"] + +[[package]] +name = "jupyter-core" +version = "5.7.2" +description = "Jupyter core package. A base package on which Jupyter projects rely." +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter_core-5.7.2-py3-none-any.whl", hash = "sha256:4f7315d2f6b4bcf2e3e7cb6e46772eba760ae459cd1f59d29eb57b0a01bd7409"}, + {file = "jupyter_core-5.7.2.tar.gz", hash = "sha256:aa5f8d32bbf6b431ac830496da7392035d6f61b4f54872f15c4bd2a9c3f536d9"}, +] + +[package.dependencies] +platformdirs = ">=2.5" +pywin32 = {version = ">=300", markers = "sys_platform == \"win32\" and platform_python_implementation != \"PyPy\""} +traitlets = ">=5.3" + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"] +test = ["ipykernel", "pre-commit", "pytest (<8)", "pytest-cov", "pytest-timeout"] + +[[package]] +name = "jupyter-events" +version = "0.10.0" +description = "Jupyter Event System library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter_events-0.10.0-py3-none-any.whl", hash = "sha256:4b72130875e59d57716d327ea70d3ebc3af1944d3717e5a498b8a06c6c159960"}, + {file = "jupyter_events-0.10.0.tar.gz", hash = "sha256:670b8229d3cc882ec782144ed22e0d29e1c2d639263f92ca8383e66682845e22"}, +] + +[package.dependencies] +jsonschema = {version = ">=4.18.0", extras = ["format-nongpl"]} +python-json-logger = ">=2.0.4" +pyyaml = ">=5.3" +referencing = "*" +rfc3339-validator = "*" +rfc3986-validator = ">=0.1.1" +traitlets = ">=5.3" + +[package.extras] +cli = ["click", "rich"] +docs = ["jupyterlite-sphinx", "myst-parser", "pydata-sphinx-theme", "sphinxcontrib-spelling"] +test = ["click", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.19.0)", "pytest-console-scripts", "rich"] + +[[package]] +name = "jupyter-lsp" +version = "2.2.5" +description = "Multi-Language Server WebSocket proxy for Jupyter Notebook/Lab server" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter-lsp-2.2.5.tar.gz", hash = "sha256:793147a05ad446f809fd53ef1cd19a9f5256fd0a2d6b7ce943a982cb4f545001"}, + {file = "jupyter_lsp-2.2.5-py3-none-any.whl", hash = "sha256:45fbddbd505f3fbfb0b6cb2f1bc5e15e83ab7c79cd6e89416b248cb3c00c11da"}, +] + +[package.dependencies] +jupyter-server = ">=1.1.2" + +[[package]] +name = "jupyter-server" +version = "2.14.1" +description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications." +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter_server-2.14.1-py3-none-any.whl", hash = "sha256:16f7177c3a4ea8fe37784e2d31271981a812f0b2874af17339031dc3510cc2a5"}, + {file = "jupyter_server-2.14.1.tar.gz", hash = "sha256:12558d158ec7a0653bf96cc272bc7ad79e0127d503b982ed144399346694f726"}, +] + +[package.dependencies] +anyio = ">=3.1.0" +argon2-cffi = ">=21.1" +jinja2 = ">=3.0.3" +jupyter-client = ">=7.4.4" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +jupyter-events = ">=0.9.0" +jupyter-server-terminals = ">=0.4.4" +nbconvert = ">=6.4.4" +nbformat = ">=5.3.0" +overrides = ">=5.0" +packaging = ">=22.0" +prometheus-client = ">=0.9" +pywinpty = {version = ">=2.0.1", markers = "os_name == \"nt\""} +pyzmq = ">=24" +send2trash = ">=1.8.2" +terminado = ">=0.8.3" +tornado = ">=6.2.0" +traitlets = ">=5.6.0" +websocket-client = ">=1.7" + +[package.extras] +docs = ["ipykernel", "jinja2", "jupyter-client", "myst-parser", "nbformat", "prometheus-client", "pydata-sphinx-theme", "send2trash", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-openapi (>=0.8.0)", "sphinxcontrib-spelling", "sphinxemoji", "tornado", "typing-extensions"] +test = ["flaky", "ipykernel", "pre-commit", "pytest (>=7.0,<9)", "pytest-console-scripts", "pytest-jupyter[server] (>=0.7)", "pytest-timeout", "requests"] + +[[package]] +name = "jupyter-server-terminals" +version = "0.5.3" +description = "A Jupyter Server Extension Providing Terminals." +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter_server_terminals-0.5.3-py3-none-any.whl", hash = "sha256:41ee0d7dc0ebf2809c668e0fc726dfaf258fcd3e769568996ca731b6194ae9aa"}, + {file = "jupyter_server_terminals-0.5.3.tar.gz", hash = "sha256:5ae0295167220e9ace0edcfdb212afd2b01ee8d179fe6f23c899590e9b8a5269"}, +] + +[package.dependencies] +pywinpty = {version = ">=2.0.3", markers = "os_name == \"nt\""} +terminado = ">=0.8.3" + +[package.extras] +docs = ["jinja2", "jupyter-server", "mistune (<4.0)", "myst-parser", "nbformat", "packaging", "pydata-sphinx-theme", "sphinxcontrib-github-alt", "sphinxcontrib-openapi", "sphinxcontrib-spelling", "sphinxemoji", "tornado"] +test = ["jupyter-server (>=2.0.0)", "pytest (>=7.0)", "pytest-jupyter[server] (>=0.5.3)", "pytest-timeout"] + +[[package]] +name = "jupyterlab" +version = "4.2.1" +description = "JupyterLab computational environment" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyterlab-4.2.1-py3-none-any.whl", hash = "sha256:6ac6e3827b3c890e6e549800e8a4f4aaea6a69321e2240007902aa7a0c56a8e4"}, + {file = "jupyterlab-4.2.1.tar.gz", hash = "sha256:a10fb71085a6900820c62d43324005046402ffc8f0fde696103e37238a839507"}, +] + +[package.dependencies] +async-lru = ">=1.0.0" +httpx = ">=0.25.0" +ipykernel = ">=6.5.0" +jinja2 = ">=3.0.3" +jupyter-core = "*" +jupyter-lsp = ">=2.0.0" +jupyter-server = ">=2.4.0,<3" +jupyterlab-server = ">=2.27.1,<3" +notebook-shim = ">=0.2" +packaging = "*" +tomli = {version = ">=1.2.2", markers = "python_version < \"3.11\""} +tornado = ">=6.2.0" +traitlets = "*" + +[package.extras] +dev = ["build", "bump2version", "coverage", "hatch", "pre-commit", "pytest-cov", "ruff (==0.3.5)"] +docs = ["jsx-lexer", "myst-parser", "pydata-sphinx-theme (>=0.13.0)", "pytest", "pytest-check-links", "pytest-jupyter", "sphinx (>=1.8,<7.3.0)", "sphinx-copybutton"] +docs-screenshots = ["altair (==5.3.0)", "ipython (==8.16.1)", "ipywidgets (==8.1.2)", "jupyterlab-geojson (==3.4.0)", "jupyterlab-language-pack-zh-cn (==4.1.post2)", "matplotlib (==3.8.3)", "nbconvert (>=7.0.0)", "pandas (==2.2.1)", "scipy (==1.12.0)", "vega-datasets (==0.9.0)"] +test = ["coverage", "pytest (>=7.0)", "pytest-check-links (>=0.7)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter (>=0.5.3)", "pytest-timeout", "pytest-tornasync", "requests", "requests-cache", "virtualenv"] +upgrade-extension = ["copier (>=8,<10)", "jinja2-time (<0.3)", "pydantic (<2.0)", "pyyaml-include (<2.0)", "tomli-w (<2.0)"] + +[[package]] +name = "jupyterlab-pygments" +version = "0.3.0" +description = "Pygments theme using JupyterLab CSS variables" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780"}, + {file = "jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d"}, +] + +[[package]] +name = "jupyterlab-server" +version = "2.27.2" +description = "A set of server components for JupyterLab and JupyterLab like applications." +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyterlab_server-2.27.2-py3-none-any.whl", hash = "sha256:54aa2d64fd86383b5438d9f0c032f043c4d8c0264b8af9f60bd061157466ea43"}, + {file = "jupyterlab_server-2.27.2.tar.gz", hash = "sha256:15cbb349dc45e954e09bacf81b9f9bcb10815ff660fb2034ecd7417db3a7ea27"}, +] + +[package.dependencies] +babel = ">=2.10" +jinja2 = ">=3.0.3" +json5 = ">=0.9.0" +jsonschema = ">=4.18.0" +jupyter-server = ">=1.21,<3" +packaging = ">=21.3" +requests = ">=2.31" + +[package.extras] +docs = ["autodoc-traits", "jinja2 (<3.2.0)", "mistune (<4)", "myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-copybutton", "sphinxcontrib-openapi (>0.8)"] +openapi = ["openapi-core (>=0.18.0,<0.19.0)", "ruamel-yaml"] +test = ["hatch", "ipykernel", "openapi-core (>=0.18.0,<0.19.0)", "openapi-spec-validator (>=0.6.0,<0.8.0)", "pytest (>=7.0,<8)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter[server] (>=0.6.2)", "pytest-timeout", "requests-mock", "ruamel-yaml", "sphinxcontrib-spelling", "strict-rfc3339", "werkzeug"] + +[[package]] +name = "jupyterlab-widgets" +version = "3.0.11" +description = "Jupyter interactive widgets for JupyterLab" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jupyterlab_widgets-3.0.11-py3-none-any.whl", hash = "sha256:78287fd86d20744ace330a61625024cf5521e1c012a352ddc0a3cdc2348becd0"}, + {file = "jupyterlab_widgets-3.0.11.tar.gz", hash = "sha256:dd5ac679593c969af29c9bed054c24f26842baa51352114736756bc035deee27"}, +] + +[[package]] +name = "langchain" +version = "0.1.20" +description = "Building applications with LLMs through composability" +optional = false +python-versions = "<4.0,>=3.8.1" +files = [ + {file = "langchain-0.1.20-py3-none-any.whl", hash = "sha256:09991999fbd6c3421a12db3c7d1f52d55601fc41d9b2a3ef51aab2e0e9c38da9"}, + {file = "langchain-0.1.20.tar.gz", hash = "sha256:f35c95eed8c8375e02dce95a34f2fd4856a4c98269d6dc34547a23dba5beab7e"}, +] + +[package.dependencies] +aiohttp = ">=3.8.3,<4.0.0" +async-timeout = {version = ">=4.0.0,<5.0.0", markers = "python_version < \"3.11\""} +dataclasses-json = ">=0.5.7,<0.7" +langchain-community = ">=0.0.38,<0.1" +langchain-core = ">=0.1.52,<0.2.0" +langchain-text-splitters = ">=0.0.1,<0.1" +langsmith = ">=0.1.17,<0.2.0" +numpy = ">=1,<2" +pydantic = ">=1,<3" +PyYAML = ">=5.3" +requests = ">=2,<3" +SQLAlchemy = ">=1.4,<3" +tenacity = ">=8.1.0,<9.0.0" + +[package.extras] +azure = ["azure-ai-formrecognizer (>=3.2.1,<4.0.0)", "azure-ai-textanalytics (>=5.3.0,<6.0.0)", "azure-cognitiveservices-speech (>=1.28.0,<2.0.0)", "azure-core (>=1.26.4,<2.0.0)", "azure-cosmos (>=4.4.0b1,<5.0.0)", "azure-identity (>=1.12.0,<2.0.0)", "azure-search-documents (==11.4.0b8)", "openai (<2)"] +clarifai = ["clarifai (>=9.1.0)"] +cli = ["typer (>=0.9.0,<0.10.0)"] +cohere = ["cohere (>=4,<6)"] +docarray = ["docarray[hnswlib] (>=0.32.0,<0.33.0)"] +embeddings = ["sentence-transformers (>=2,<3)"] +extended-testing = ["aiosqlite (>=0.19.0,<0.20.0)", "aleph-alpha-client (>=2.15.0,<3.0.0)", "anthropic (>=0.3.11,<0.4.0)", "arxiv (>=1.4,<2.0)", "assemblyai (>=0.17.0,<0.18.0)", "atlassian-python-api (>=3.36.0,<4.0.0)", "beautifulsoup4 (>=4,<5)", "bibtexparser (>=1.4.0,<2.0.0)", "cassio (>=0.1.0,<0.2.0)", "chardet (>=5.1.0,<6.0.0)", "cohere (>=4,<6)", "couchbase (>=4.1.9,<5.0.0)", "dashvector (>=1.0.1,<2.0.0)", "databricks-vectorsearch (>=0.21,<0.22)", "datasets (>=2.15.0,<3.0.0)", "dgml-utils (>=0.3.0,<0.4.0)", "esprima (>=4.0.1,<5.0.0)", "faiss-cpu (>=1,<2)", "feedparser (>=6.0.10,<7.0.0)", "fireworks-ai (>=0.9.0,<0.10.0)", "geopandas (>=0.13.1,<0.14.0)", "gitpython (>=3.1.32,<4.0.0)", "google-cloud-documentai (>=2.20.1,<3.0.0)", "gql (>=3.4.1,<4.0.0)", "hologres-vector (>=0.0.6,<0.0.7)", "html2text (>=2020.1.16,<2021.0.0)", "javelin-sdk (>=0.1.8,<0.2.0)", "jinja2 (>=3,<4)", "jq (>=1.4.1,<2.0.0)", "jsonschema (>1)", "langchain-openai (>=0.0.2,<0.1)", "lxml (>=4.9.3,<6.0)", "markdownify (>=0.11.6,<0.12.0)", "motor (>=3.3.1,<4.0.0)", "msal (>=1.25.0,<2.0.0)", "mwparserfromhell (>=0.6.4,<0.7.0)", "mwxml (>=0.3.3,<0.4.0)", "newspaper3k (>=0.2.8,<0.3.0)", "numexpr (>=2.8.6,<3.0.0)", "openai (<2)", "openapi-pydantic (>=0.3.2,<0.4.0)", "pandas (>=2.0.1,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "pgvector (>=0.1.6,<0.2.0)", "praw (>=7.7.1,<8.0.0)", "psychicapi (>=0.8.0,<0.9.0)", "py-trello (>=0.19.0,<0.20.0)", "pymupdf (>=1.22.3,<2.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pypdfium2 (>=4.10.0,<5.0.0)", "pyspark (>=3.4.0,<4.0.0)", "rank-bm25 (>=0.2.2,<0.3.0)", "rapidfuzz (>=3.1.1,<4.0.0)", "rapidocr-onnxruntime (>=1.3.2,<2.0.0)", "rdflib (==7.0.0)", "requests-toolbelt (>=1.0.0,<2.0.0)", "rspace_client (>=2.5.0,<3.0.0)", "scikit-learn (>=1.2.2,<2.0.0)", "sqlite-vss (>=0.1.2,<0.2.0)", "streamlit (>=1.18.0,<2.0.0)", "sympy (>=1.12,<2.0)", "telethon (>=1.28.5,<2.0.0)", "timescale-vector (>=0.0.1,<0.0.2)", "tqdm (>=4.48.0)", "upstash-redis (>=0.15.0,<0.16.0)", "xata (>=1.0.0a7,<2.0.0)", "xmltodict (>=0.13.0,<0.14.0)"] +javascript = ["esprima (>=4.0.1,<5.0.0)"] +llms = ["clarifai (>=9.1.0)", "cohere (>=4,<6)", "huggingface_hub (>=0,<1)", "manifest-ml (>=0.0.1,<0.0.2)", "nlpcloud (>=1,<2)", "openai (<2)", "openlm (>=0.0.5,<0.0.6)", "torch (>=1,<3)", "transformers (>=4,<5)"] +openai = ["openai (<2)", "tiktoken (>=0.3.2,<0.6.0)"] +qdrant = ["qdrant-client (>=1.3.1,<2.0.0)"] +text-helpers = ["chardet (>=5.1.0,<6.0.0)"] + +[[package]] +name = "langchain-community" +version = "0.0.38" +description = "Community contributed LangChain integrations." +optional = false +python-versions = "<4.0,>=3.8.1" +files = [ + {file = "langchain_community-0.0.38-py3-none-any.whl", hash = "sha256:ecb48660a70a08c90229be46b0cc5f6bc9f38f2833ee44c57dfab9bf3a2c121a"}, + {file = "langchain_community-0.0.38.tar.gz", hash = "sha256:127fc4b75bc67b62fe827c66c02e715a730fef8fe69bd2023d466bab06b5810d"}, +] + +[package.dependencies] +aiohttp = ">=3.8.3,<4.0.0" +dataclasses-json = ">=0.5.7,<0.7" +langchain-core = ">=0.1.52,<0.2.0" +langsmith = ">=0.1.0,<0.2.0" +numpy = ">=1,<2" +PyYAML = ">=5.3" +requests = ">=2,<3" +SQLAlchemy = ">=1.4,<3" +tenacity = ">=8.1.0,<9.0.0" + +[package.extras] +cli = ["typer (>=0.9.0,<0.10.0)"] +extended-testing = ["aiosqlite (>=0.19.0,<0.20.0)", "aleph-alpha-client (>=2.15.0,<3.0.0)", "anthropic (>=0.3.11,<0.4.0)", "arxiv (>=1.4,<2.0)", "assemblyai (>=0.17.0,<0.18.0)", "atlassian-python-api (>=3.36.0,<4.0.0)", "azure-ai-documentintelligence (>=1.0.0b1,<2.0.0)", "azure-identity (>=1.15.0,<2.0.0)", "azure-search-documents (==11.4.0)", "beautifulsoup4 (>=4,<5)", "bibtexparser (>=1.4.0,<2.0.0)", "cassio (>=0.1.6,<0.2.0)", "chardet (>=5.1.0,<6.0.0)", "cloudpickle (>=2.0.0)", "cohere (>=4,<5)", "databricks-vectorsearch (>=0.21,<0.22)", "datasets (>=2.15.0,<3.0.0)", "dgml-utils (>=0.3.0,<0.4.0)", "elasticsearch (>=8.12.0,<9.0.0)", "esprima (>=4.0.1,<5.0.0)", "faiss-cpu (>=1,<2)", "feedparser (>=6.0.10,<7.0.0)", "fireworks-ai (>=0.9.0,<0.10.0)", "friendli-client (>=1.2.4,<2.0.0)", "geopandas (>=0.13.1,<0.14.0)", "gitpython (>=3.1.32,<4.0.0)", "google-cloud-documentai (>=2.20.1,<3.0.0)", "gql (>=3.4.1,<4.0.0)", "gradientai (>=1.4.0,<2.0.0)", "hdbcli (>=2.19.21,<3.0.0)", "hologres-vector (>=0.0.6,<0.0.7)", "html2text (>=2020.1.16,<2021.0.0)", "httpx (>=0.24.1,<0.25.0)", "httpx-sse (>=0.4.0,<0.5.0)", "javelin-sdk (>=0.1.8,<0.2.0)", "jinja2 (>=3,<4)", "jq (>=1.4.1,<2.0.0)", "jsonschema (>1)", "lxml (>=4.9.3,<6.0)", "markdownify (>=0.11.6,<0.12.0)", "motor (>=3.3.1,<4.0.0)", "msal (>=1.25.0,<2.0.0)", "mwparserfromhell (>=0.6.4,<0.7.0)", "mwxml (>=0.3.3,<0.4.0)", "newspaper3k (>=0.2.8,<0.3.0)", "numexpr (>=2.8.6,<3.0.0)", "nvidia-riva-client (>=2.14.0,<3.0.0)", "oci (>=2.119.1,<3.0.0)", "openai (<2)", "openapi-pydantic (>=0.3.2,<0.4.0)", "oracle-ads (>=2.9.1,<3.0.0)", "oracledb (>=2.2.0,<3.0.0)", "pandas (>=2.0.1,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "pgvector (>=0.1.6,<0.2.0)", "praw (>=7.7.1,<8.0.0)", "premai (>=0.3.25,<0.4.0)", "psychicapi (>=0.8.0,<0.9.0)", "py-trello (>=0.19.0,<0.20.0)", "pyjwt (>=2.8.0,<3.0.0)", "pymupdf (>=1.22.3,<2.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pypdfium2 (>=4.10.0,<5.0.0)", "pyspark (>=3.4.0,<4.0.0)", "rank-bm25 (>=0.2.2,<0.3.0)", "rapidfuzz (>=3.1.1,<4.0.0)", "rapidocr-onnxruntime (>=1.3.2,<2.0.0)", "rdflib (==7.0.0)", "requests-toolbelt (>=1.0.0,<2.0.0)", "rspace_client (>=2.5.0,<3.0.0)", "scikit-learn (>=1.2.2,<2.0.0)", "sqlite-vss (>=0.1.2,<0.2.0)", "streamlit (>=1.18.0,<2.0.0)", "sympy (>=1.12,<2.0)", "telethon (>=1.28.5,<2.0.0)", "tidb-vector (>=0.0.3,<1.0.0)", "timescale-vector (>=0.0.1,<0.0.2)", "tqdm (>=4.48.0)", "tree-sitter (>=0.20.2,<0.21.0)", "tree-sitter-languages (>=1.8.0,<2.0.0)", "upstash-redis (>=0.15.0,<0.16.0)", "vdms (>=0.0.20,<0.0.21)", "xata (>=1.0.0a7,<2.0.0)", "xmltodict (>=0.13.0,<0.14.0)"] + +[[package]] +name = "langchain-core" +version = "0.1.52" +description = "Building applications with LLMs through composability" +optional = false +python-versions = "<4.0,>=3.8.1" +files = [ + {file = "langchain_core-0.1.52-py3-none-any.whl", hash = "sha256:62566749c92e8a1181c255c788548dc16dbc319d896cd6b9c95dc17af9b2a6db"}, + {file = "langchain_core-0.1.52.tar.gz", hash = "sha256:084c3fc452f5a6966c28ab3ec5dbc8b8d26fc3f63378073928f4e29d90b6393f"}, +] + +[package.dependencies] +jsonpatch = ">=1.33,<2.0" +langsmith = ">=0.1.0,<0.2.0" +packaging = ">=23.2,<24.0" +pydantic = ">=1,<3" +PyYAML = ">=5.3" +tenacity = ">=8.1.0,<9.0.0" + +[package.extras] +extended-testing = ["jinja2 (>=3,<4)"] + +[[package]] +name = "langchain-openai" +version = "0.1.6" +description = "An integration package connecting OpenAI and LangChain" +optional = false +python-versions = "<4.0,>=3.8.1" +files = [ + {file = "langchain_openai-0.1.6-py3-none-any.whl", hash = "sha256:7f62ecb12d3cdd0d96679abea00e4e3ceb1f829f6d1f127a5f7b97c1315d157f"}, + {file = "langchain_openai-0.1.6.tar.gz", hash = "sha256:7d2e838e57ef231cb7689fd58ac5fa8a6e9e504174f8c5698c837739786e2030"}, +] + +[package.dependencies] +langchain-core = ">=0.1.46,<0.2.0" +openai = ">=1.24.0,<2.0.0" +tiktoken = ">=0.5.2,<1" + +[[package]] +name = "langchain-text-splitters" +version = "0.0.2" +description = "LangChain text splitting utilities" +optional = false +python-versions = "<4.0,>=3.8.1" +files = [ + {file = "langchain_text_splitters-0.0.2-py3-none-any.whl", hash = "sha256:13887f32705862c1e1454213cb7834a63aae57c26fcd80346703a1d09c46168d"}, + {file = "langchain_text_splitters-0.0.2.tar.gz", hash = "sha256:ac8927dc0ba08eba702f6961c9ed7df7cead8de19a9f7101ab2b5ea34201b3c1"}, +] + +[package.dependencies] +langchain-core = ">=0.1.28,<0.3" + +[package.extras] +extended-testing = ["beautifulsoup4 (>=4.12.3,<5.0.0)", "lxml (>=4.9.3,<6.0)"] + +[[package]] +name = "langsmith" +version = "0.1.67" +description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." +optional = false +python-versions = "<4.0,>=3.8.1" +files = [ + {file = "langsmith-0.1.67-py3-none-any.whl", hash = "sha256:7eb2e1c1b375925ff47700ed8071e10c15e942e9d1d634b4a449a9060364071a"}, + {file = "langsmith-0.1.67.tar.gz", hash = "sha256:149558669a2ac4f21471cd964e61072687bba23b7c1ccb51f190a8f59b595b39"}, +] + +[package.dependencies] +orjson = ">=3.9.14,<4.0.0" +pydantic = ">=1,<3" +requests = ">=2,<3" + [[package]] name = "libcst" version = "1.4.0" @@ -1607,13 +2628,13 @@ dev = ["Sphinx (>=5.1.1)", "black (==23.12.1)", "build (>=0.10.0)", "coverage (> [[package]] name = "litellm" -version = "1.40.4" +version = "1.40.0" description = "Library to easily interface with LLM API providers" optional = false python-versions = "!=2.7.*,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,!=3.7.*,>=3.8" files = [ - {file = "litellm-1.40.4-py3-none-any.whl", hash = "sha256:b3b8e4401f717c3a18595446bfdb80fc6bb74974aac4eae537fb7b3be37fbf9e"}, - {file = "litellm-1.40.4.tar.gz", hash = "sha256:3edaa1189742afd7c7df2b122f77373d47154a8fb6df6187ff5875e188baa3e1"}, + {file = "litellm-1.40.0-py3-none-any.whl", hash = "sha256:c3055767ae144585699fdb07b3ad678e66738c2eff19abd7761c8fe22d6e636f"}, + {file = "litellm-1.40.0.tar.gz", hash = "sha256:12b4c0ad850ede5aebdb2f48e3a8e898efb25df5bc915ff89929ad963cb92f54"}, ] [package.dependencies] @@ -1631,6 +2652,17 @@ tokenizers = "*" extra-proxy = ["azure-identity (>=1.15.0,<2.0.0)", "azure-keyvault-secrets (>=4.8.0,<5.0.0)", "google-cloud-kms (>=2.21.3,<3.0.0)", "prisma (==0.11.0)", "resend (>=0.8.0,<0.9.0)"] proxy = ["PyJWT (>=2.8.0,<3.0.0)", "apscheduler (>=3.10.4,<4.0.0)", "backoff", "cryptography (>=42.0.5,<43.0.0)", "fastapi (>=0.111.0,<0.112.0)", "fastapi-sso (>=0.10.0,<0.11.0)", "gunicorn (>=22.0.0,<23.0.0)", "orjson (>=3.9.7,<4.0.0)", "python-multipart (>=0.0.9,<0.0.10)", "pyyaml (>=6.0.1,<7.0.0)", "rq", "uvicorn (>=0.22.0,<0.23.0)"] +[[package]] +name = "locket" +version = "1.0.0" +description = "File-based locks for Python on Linux and Windows" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "locket-1.0.0-py2.py3-none-any.whl", hash = "sha256:b6c819a722f7b6bd955b80781788e4a66a55628b858d347536b7e81325a3a5e3"}, + {file = "locket-1.0.0.tar.gz", hash = "sha256:5c0d4c052a8bbbf750e056a8e65ccd309086f4f0f18a2eac306a8dfa4112a632"}, +] + [[package]] name = "markdown-it-py" version = "3.0.0" @@ -1726,13 +2758,13 @@ files = [ [[package]] name = "marshmallow" -version = "3.21.3" +version = "3.21.2" description = "A lightweight library for converting complex datatypes to and from native Python datatypes." optional = false python-versions = ">=3.8" files = [ - {file = "marshmallow-3.21.3-py3-none-any.whl", hash = "sha256:86ce7fb914aa865001a4b2092c4c2872d13bc347f3d42673272cabfdbad386f1"}, - {file = "marshmallow-3.21.3.tar.gz", hash = "sha256:4f57c5e050a54d66361e826f94fba213eb10b67b2fdb02c3e0343ce207ba1662"}, + {file = "marshmallow-3.21.2-py3-none-any.whl", hash = "sha256:70b54a6282f4704d12c0a41599682c5c5450e843b9ec406308653b47c59648a1"}, + {file = "marshmallow-3.21.2.tar.gz", hash = "sha256:82408deadd8b33d56338d2182d455db632c6313aa2af61916672146bb32edc56"}, ] [package.dependencies] @@ -1768,6 +2800,82 @@ files = [ {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, ] +[[package]] +name = "mistune" +version = "3.0.2" +description = "A sane and fast Markdown parser with useful plugins and renderers" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mistune-3.0.2-py3-none-any.whl", hash = "sha256:71481854c30fdbc938963d3605b72501f5c10a9320ecd412c121c163a1c7d205"}, + {file = "mistune-3.0.2.tar.gz", hash = "sha256:fc7f93ded930c92394ef2cb6f04a8aabab4117a91449e72dcc8dfa646a508be8"}, +] + +[[package]] +name = "msgpack" +version = "1.0.8" +description = "MessagePack serializer" +optional = false +python-versions = ">=3.8" +files = [ + {file = "msgpack-1.0.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:505fe3d03856ac7d215dbe005414bc28505d26f0c128906037e66d98c4e95868"}, + {file = "msgpack-1.0.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6b7842518a63a9f17107eb176320960ec095a8ee3b4420b5f688e24bf50c53c"}, + {file = "msgpack-1.0.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:376081f471a2ef24828b83a641a02c575d6103a3ad7fd7dade5486cad10ea659"}, + {file = "msgpack-1.0.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e390971d082dba073c05dbd56322427d3280b7cc8b53484c9377adfbae67dc2"}, + {file = "msgpack-1.0.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00e073efcba9ea99db5acef3959efa45b52bc67b61b00823d2a1a6944bf45982"}, + {file = "msgpack-1.0.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82d92c773fbc6942a7a8b520d22c11cfc8fd83bba86116bfcf962c2f5c2ecdaa"}, + {file = "msgpack-1.0.8-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9ee32dcb8e531adae1f1ca568822e9b3a738369b3b686d1477cbc643c4a9c128"}, + {file = "msgpack-1.0.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e3aa7e51d738e0ec0afbed661261513b38b3014754c9459508399baf14ae0c9d"}, + {file = "msgpack-1.0.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:69284049d07fce531c17404fcba2bb1df472bc2dcdac642ae71a2d079d950653"}, + {file = "msgpack-1.0.8-cp310-cp310-win32.whl", hash = "sha256:13577ec9e247f8741c84d06b9ece5f654920d8365a4b636ce0e44f15e07ec693"}, + {file = "msgpack-1.0.8-cp310-cp310-win_amd64.whl", hash = "sha256:e532dbd6ddfe13946de050d7474e3f5fb6ec774fbb1a188aaf469b08cf04189a"}, + {file = "msgpack-1.0.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9517004e21664f2b5a5fd6333b0731b9cf0817403a941b393d89a2f1dc2bd836"}, + {file = "msgpack-1.0.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d16a786905034e7e34098634b184a7d81f91d4c3d246edc6bd7aefb2fd8ea6ad"}, + {file = "msgpack-1.0.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2872993e209f7ed04d963e4b4fbae72d034844ec66bc4ca403329db2074377b"}, + {file = "msgpack-1.0.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c330eace3dd100bdb54b5653b966de7f51c26ec4a7d4e87132d9b4f738220ba"}, + {file = "msgpack-1.0.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83b5c044f3eff2a6534768ccfd50425939e7a8b5cf9a7261c385de1e20dcfc85"}, + {file = "msgpack-1.0.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1876b0b653a808fcd50123b953af170c535027bf1d053b59790eebb0aeb38950"}, + {file = "msgpack-1.0.8-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:dfe1f0f0ed5785c187144c46a292b8c34c1295c01da12e10ccddfc16def4448a"}, + {file = "msgpack-1.0.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3528807cbbb7f315bb81959d5961855e7ba52aa60a3097151cb21956fbc7502b"}, + {file = "msgpack-1.0.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e2f879ab92ce502a1e65fce390eab619774dda6a6ff719718069ac94084098ce"}, + {file = "msgpack-1.0.8-cp311-cp311-win32.whl", hash = "sha256:26ee97a8261e6e35885c2ecd2fd4a6d38252246f94a2aec23665a4e66d066305"}, + {file = "msgpack-1.0.8-cp311-cp311-win_amd64.whl", hash = "sha256:eadb9f826c138e6cf3c49d6f8de88225a3c0ab181a9b4ba792e006e5292d150e"}, + {file = "msgpack-1.0.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:114be227f5213ef8b215c22dde19532f5da9652e56e8ce969bf0a26d7c419fee"}, + {file = "msgpack-1.0.8-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d661dc4785affa9d0edfdd1e59ec056a58b3dbb9f196fa43587f3ddac654ac7b"}, + {file = "msgpack-1.0.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d56fd9f1f1cdc8227d7b7918f55091349741904d9520c65f0139a9755952c9e8"}, + {file = "msgpack-1.0.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0726c282d188e204281ebd8de31724b7d749adebc086873a59efb8cf7ae27df3"}, + {file = "msgpack-1.0.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8db8e423192303ed77cff4dce3a4b88dbfaf43979d280181558af5e2c3c71afc"}, + {file = "msgpack-1.0.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99881222f4a8c2f641f25703963a5cefb076adffd959e0558dc9f803a52d6a58"}, + {file = "msgpack-1.0.8-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b5505774ea2a73a86ea176e8a9a4a7c8bf5d521050f0f6f8426afe798689243f"}, + {file = "msgpack-1.0.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ef254a06bcea461e65ff0373d8a0dd1ed3aa004af48839f002a0c994a6f72d04"}, + {file = "msgpack-1.0.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e1dd7839443592d00e96db831eddb4111a2a81a46b028f0facd60a09ebbdd543"}, + {file = "msgpack-1.0.8-cp312-cp312-win32.whl", hash = "sha256:64d0fcd436c5683fdd7c907eeae5e2cbb5eb872fafbc03a43609d7941840995c"}, + {file = "msgpack-1.0.8-cp312-cp312-win_amd64.whl", hash = "sha256:74398a4cf19de42e1498368c36eed45d9528f5fd0155241e82c4082b7e16cffd"}, + {file = "msgpack-1.0.8-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0ceea77719d45c839fd73abcb190b8390412a890df2f83fb8cf49b2a4b5c2f40"}, + {file = "msgpack-1.0.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1ab0bbcd4d1f7b6991ee7c753655b481c50084294218de69365f8f1970d4c151"}, + {file = "msgpack-1.0.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1cce488457370ffd1f953846f82323cb6b2ad2190987cd4d70b2713e17268d24"}, + {file = "msgpack-1.0.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3923a1778f7e5ef31865893fdca12a8d7dc03a44b33e2a5f3295416314c09f5d"}, + {file = "msgpack-1.0.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a22e47578b30a3e199ab067a4d43d790249b3c0587d9a771921f86250c8435db"}, + {file = "msgpack-1.0.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd739c9251d01e0279ce729e37b39d49a08c0420d3fee7f2a4968c0576678f77"}, + {file = "msgpack-1.0.8-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d3420522057ebab1728b21ad473aa950026d07cb09da41103f8e597dfbfaeb13"}, + {file = "msgpack-1.0.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5845fdf5e5d5b78a49b826fcdc0eb2e2aa7191980e3d2cfd2a30303a74f212e2"}, + {file = "msgpack-1.0.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a0e76621f6e1f908ae52860bdcb58e1ca85231a9b0545e64509c931dd34275a"}, + {file = "msgpack-1.0.8-cp38-cp38-win32.whl", hash = "sha256:374a8e88ddab84b9ada695d255679fb99c53513c0a51778796fcf0944d6c789c"}, + {file = "msgpack-1.0.8-cp38-cp38-win_amd64.whl", hash = "sha256:f3709997b228685fe53e8c433e2df9f0cdb5f4542bd5114ed17ac3c0129b0480"}, + {file = "msgpack-1.0.8-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f51bab98d52739c50c56658cc303f190785f9a2cd97b823357e7aeae54c8f68a"}, + {file = "msgpack-1.0.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:73ee792784d48aa338bba28063e19a27e8d989344f34aad14ea6e1b9bd83f596"}, + {file = "msgpack-1.0.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f9904e24646570539a8950400602d66d2b2c492b9010ea7e965025cb71d0c86d"}, + {file = "msgpack-1.0.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e75753aeda0ddc4c28dce4c32ba2f6ec30b1b02f6c0b14e547841ba5b24f753f"}, + {file = "msgpack-1.0.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5dbf059fb4b7c240c873c1245ee112505be27497e90f7c6591261c7d3c3a8228"}, + {file = "msgpack-1.0.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4916727e31c28be8beaf11cf117d6f6f188dcc36daae4e851fee88646f5b6b18"}, + {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7938111ed1358f536daf311be244f34df7bf3cdedb3ed883787aca97778b28d8"}, + {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:493c5c5e44b06d6c9268ce21b302c9ca055c1fd3484c25ba41d34476c76ee746"}, + {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5fbb160554e319f7b22ecf530a80a3ff496d38e8e07ae763b9e82fadfe96f273"}, + {file = "msgpack-1.0.8-cp39-cp39-win32.whl", hash = "sha256:f9af38a89b6a5c04b7d18c492c8ccf2aee7048aff1ce8437c4683bb5a1df893d"}, + {file = "msgpack-1.0.8-cp39-cp39-win_amd64.whl", hash = "sha256:ed59dd52075f8fc91da6053b12e8c89e37aa043f8986efd89e61fae69dc1b011"}, + {file = "msgpack-1.0.8.tar.gz", hash = "sha256:95c02b0e27e706e48d0e5426d1710ca78e0f0628d6e89d5b5a5b91a5f12274f3"}, +] + [[package]] name = "msgspec" version = "0.18.6" @@ -1920,14 +3028,105 @@ files = [ ] [[package]] -name = "mypy-extensions" -version = "1.0.0" -description = "Type system extensions for programs checked with the mypy type checker." +name = "mypy-extensions" +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." +optional = false +python-versions = ">=3.5" +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] + +[[package]] +name = "nbclient" +version = "0.10.0" +description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "nbclient-0.10.0-py3-none-any.whl", hash = "sha256:f13e3529332a1f1f81d82a53210322476a168bb7090a0289c795fe9cc11c9d3f"}, + {file = "nbclient-0.10.0.tar.gz", hash = "sha256:4b3f1b7dba531e498449c4db4f53da339c91d449dc11e9af3a43b4eb5c5abb09"}, +] + +[package.dependencies] +jupyter-client = ">=6.1.12" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +nbformat = ">=5.1" +traitlets = ">=5.4" + +[package.extras] +dev = ["pre-commit"] +docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient[test]", "sphinx (>=1.7)", "sphinx-book-theme", "sphinxcontrib-spelling"] +test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0,<8)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] + +[[package]] +name = "nbconvert" +version = "7.16.4" +description = "Converting Jupyter Notebooks (.ipynb files) to other formats. Output formats include asciidoc, html, latex, markdown, pdf, py, rst, script. nbconvert can be used both as a Python library (`import nbconvert`) or as a command line tool (invoked as `jupyter nbconvert ...`)." +optional = false +python-versions = ">=3.8" +files = [ + {file = "nbconvert-7.16.4-py3-none-any.whl", hash = "sha256:05873c620fe520b6322bf8a5ad562692343fe3452abda5765c7a34b7d1aa3eb3"}, + {file = "nbconvert-7.16.4.tar.gz", hash = "sha256:86ca91ba266b0a448dc96fa6c5b9d98affabde2867b363258703536807f9f7f4"}, +] + +[package.dependencies] +beautifulsoup4 = "*" +bleach = "!=5.0.0" +defusedxml = "*" +jinja2 = ">=3.0" +jupyter-core = ">=4.7" +jupyterlab-pygments = "*" +markupsafe = ">=2.0" +mistune = ">=2.0.3,<4" +nbclient = ">=0.5.0" +nbformat = ">=5.7" +packaging = "*" +pandocfilters = ">=1.4.1" +pygments = ">=2.4.1" +tinycss2 = "*" +traitlets = ">=5.1" + +[package.extras] +all = ["flaky", "ipykernel", "ipython", "ipywidgets (>=7.5)", "myst-parser", "nbsphinx (>=0.2.12)", "playwright", "pydata-sphinx-theme", "pyqtwebengine (>=5.15)", "pytest (>=7)", "sphinx (==5.0.2)", "sphinxcontrib-spelling", "tornado (>=6.1)"] +docs = ["ipykernel", "ipython", "myst-parser", "nbsphinx (>=0.2.12)", "pydata-sphinx-theme", "sphinx (==5.0.2)", "sphinxcontrib-spelling"] +qtpdf = ["pyqtwebengine (>=5.15)"] +qtpng = ["pyqtwebengine (>=5.15)"] +serve = ["tornado (>=6.1)"] +test = ["flaky", "ipykernel", "ipywidgets (>=7.5)", "pytest (>=7)"] +webpdf = ["playwright"] + +[[package]] +name = "nbformat" +version = "5.10.4" +description = "The Jupyter Notebook format" +optional = false +python-versions = ">=3.8" +files = [ + {file = "nbformat-5.10.4-py3-none-any.whl", hash = "sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b"}, + {file = "nbformat-5.10.4.tar.gz", hash = "sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a"}, +] + +[package.dependencies] +fastjsonschema = ">=2.15" +jsonschema = ">=2.6" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +traitlets = ">=5.1" + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] +test = ["pep440", "pre-commit", "pytest", "testpath"] + +[[package]] +name = "nest-asyncio" +version = "1.6.0" +description = "Patch asyncio to allow nested event loops" optional = false python-versions = ">=3.5" files = [ - {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, - {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, + {file = "nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c"}, + {file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"}, ] [[package]] @@ -1975,6 +3174,23 @@ files = [ [package.extras] test = ["codecov (>=2.0.5)", "coverage (>=4.2)", "flake8 (>=3.0.4)", "pytest (>=4.5.0)", "pytest-cov (>=2.7.1)", "pytest-runner (>=5.1)", "pytest-virtualenv (>=1.7.0)", "virtualenv (>=15.0.3)"] +[[package]] +name = "notebook-shim" +version = "0.2.4" +description = "A shim layer for notebook traits and config" +optional = false +python-versions = ">=3.7" +files = [ + {file = "notebook_shim-0.2.4-py3-none-any.whl", hash = "sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef"}, + {file = "notebook_shim-0.2.4.tar.gz", hash = "sha256:b4b2cfa1b65d98307ca24361f5b30fe785b53c3fd07b7a47e89acb5e6ac638cb"}, +] + +[package.dependencies] +jupyter-server = ">=1.8,<3" + +[package.extras] +test = ["pytest", "pytest-console-scripts", "pytest-jupyter", "pytest-tornasync"] + [[package]] name = "numpy" version = "1.26.4" @@ -2022,13 +3238,13 @@ files = [ [[package]] name = "openai" -version = "1.31.2" +version = "1.30.5" description = "The official Python library for the openai API" optional = false python-versions = ">=3.7.1" files = [ - {file = "openai-1.31.2-py3-none-any.whl", hash = "sha256:203cf21294f347c3d7b591e0ccbe18389d6f8967d4237214b926ea76b1e1781c"}, - {file = "openai-1.31.2.tar.gz", hash = "sha256:966ab3165b926cb5ec091d2434c90613e2ea8b73ffad984f7fec34bde971725a"}, + {file = "openai-1.30.5-py3-none-any.whl", hash = "sha256:2ad95e926de0d2e09cde632a9204b0a6dca4a03c2cdcc84329b01f355784355a"}, + {file = "openai-1.30.5.tar.gz", hash = "sha256:5366562eb2c5917e6116ae0391b7ae6e3acd62b0ae3f565ada32b35d8fcfa106"}, ] [package.dependencies] @@ -2043,15 +3259,81 @@ typing-extensions = ">=4.7,<5" [package.extras] datalib = ["numpy (>=1)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"] +[[package]] +name = "orjson" +version = "3.10.3" +description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" +optional = false +python-versions = ">=3.8" +files = [ + {file = "orjson-3.10.3-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:9fb6c3f9f5490a3eb4ddd46fc1b6eadb0d6fc16fb3f07320149c3286a1409dd8"}, + {file = "orjson-3.10.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:252124b198662eee80428f1af8c63f7ff077c88723fe206a25df8dc57a57b1fa"}, + {file = "orjson-3.10.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9f3e87733823089a338ef9bbf363ef4de45e5c599a9bf50a7a9b82e86d0228da"}, + {file = "orjson-3.10.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c8334c0d87103bb9fbbe59b78129f1f40d1d1e8355bbed2ca71853af15fa4ed3"}, + {file = "orjson-3.10.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1952c03439e4dce23482ac846e7961f9d4ec62086eb98ae76d97bd41d72644d7"}, + {file = "orjson-3.10.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c0403ed9c706dcd2809f1600ed18f4aae50be263bd7112e54b50e2c2bc3ebd6d"}, + {file = "orjson-3.10.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:382e52aa4270a037d41f325e7d1dfa395b7de0c367800b6f337d8157367bf3a7"}, + {file = "orjson-3.10.3-cp310-none-win32.whl", hash = "sha256:be2aab54313752c04f2cbaab4515291ef5af8c2256ce22abc007f89f42f49109"}, + {file = "orjson-3.10.3-cp310-none-win_amd64.whl", hash = "sha256:416b195f78ae461601893f482287cee1e3059ec49b4f99479aedf22a20b1098b"}, + {file = "orjson-3.10.3-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:73100d9abbbe730331f2242c1fc0bcb46a3ea3b4ae3348847e5a141265479700"}, + {file = "orjson-3.10.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:544a12eee96e3ab828dbfcb4d5a0023aa971b27143a1d35dc214c176fdfb29b3"}, + {file = "orjson-3.10.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:520de5e2ef0b4ae546bea25129d6c7c74edb43fc6cf5213f511a927f2b28148b"}, + {file = "orjson-3.10.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ccaa0a401fc02e8828a5bedfd80f8cd389d24f65e5ca3954d72c6582495b4bcf"}, + {file = "orjson-3.10.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a7bc9e8bc11bac40f905640acd41cbeaa87209e7e1f57ade386da658092dc16"}, + {file = "orjson-3.10.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3582b34b70543a1ed6944aca75e219e1192661a63da4d039d088a09c67543b08"}, + {file = "orjson-3.10.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1c23dfa91481de880890d17aa7b91d586a4746a4c2aa9a145bebdbaf233768d5"}, + {file = "orjson-3.10.3-cp311-none-win32.whl", hash = "sha256:1770e2a0eae728b050705206d84eda8b074b65ee835e7f85c919f5705b006c9b"}, + {file = "orjson-3.10.3-cp311-none-win_amd64.whl", hash = "sha256:93433b3c1f852660eb5abdc1f4dd0ced2be031ba30900433223b28ee0140cde5"}, + {file = "orjson-3.10.3-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a39aa73e53bec8d410875683bfa3a8edf61e5a1c7bb4014f65f81d36467ea098"}, + {file = "orjson-3.10.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0943a96b3fa09bee1afdfccc2cb236c9c64715afa375b2af296c73d91c23eab2"}, + {file = "orjson-3.10.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e852baafceff8da3c9defae29414cc8513a1586ad93e45f27b89a639c68e8176"}, + {file = "orjson-3.10.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18566beb5acd76f3769c1d1a7ec06cdb81edc4d55d2765fb677e3eaa10fa99e0"}, + {file = "orjson-3.10.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bd2218d5a3aa43060efe649ec564ebedec8ce6ae0a43654b81376216d5ebd42"}, + {file = "orjson-3.10.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:cf20465e74c6e17a104ecf01bf8cd3b7b252565b4ccee4548f18b012ff2f8069"}, + {file = "orjson-3.10.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ba7f67aa7f983c4345eeda16054a4677289011a478ca947cd69c0a86ea45e534"}, + {file = "orjson-3.10.3-cp312-none-win32.whl", hash = "sha256:17e0713fc159abc261eea0f4feda611d32eabc35708b74bef6ad44f6c78d5ea0"}, + {file = "orjson-3.10.3-cp312-none-win_amd64.whl", hash = "sha256:4c895383b1ec42b017dd2c75ae8a5b862fc489006afde06f14afbdd0309b2af0"}, + {file = "orjson-3.10.3-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:be2719e5041e9fb76c8c2c06b9600fe8e8584e6980061ff88dcbc2691a16d20d"}, + {file = "orjson-3.10.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0175a5798bdc878956099f5c54b9837cb62cfbf5d0b86ba6d77e43861bcec2"}, + {file = "orjson-3.10.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:978be58a68ade24f1af7758626806e13cff7748a677faf95fbb298359aa1e20d"}, + {file = "orjson-3.10.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16bda83b5c61586f6f788333d3cf3ed19015e3b9019188c56983b5a299210eb5"}, + {file = "orjson-3.10.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ad1f26bea425041e0a1adad34630c4825a9e3adec49079b1fb6ac8d36f8b754"}, + {file = "orjson-3.10.3-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:9e253498bee561fe85d6325ba55ff2ff08fb5e7184cd6a4d7754133bd19c9195"}, + {file = "orjson-3.10.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0a62f9968bab8a676a164263e485f30a0b748255ee2f4ae49a0224be95f4532b"}, + {file = "orjson-3.10.3-cp38-none-win32.whl", hash = "sha256:8d0b84403d287d4bfa9bf7d1dc298d5c1c5d9f444f3737929a66f2fe4fb8f134"}, + {file = "orjson-3.10.3-cp38-none-win_amd64.whl", hash = "sha256:8bc7a4df90da5d535e18157220d7915780d07198b54f4de0110eca6b6c11e290"}, + {file = "orjson-3.10.3-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:9059d15c30e675a58fdcd6f95465c1522b8426e092de9fff20edebfdc15e1cb0"}, + {file = "orjson-3.10.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d40c7f7938c9c2b934b297412c067936d0b54e4b8ab916fd1a9eb8f54c02294"}, + {file = "orjson-3.10.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d4a654ec1de8fdaae1d80d55cee65893cb06494e124681ab335218be6a0691e7"}, + {file = "orjson-3.10.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:831c6ef73f9aa53c5f40ae8f949ff7681b38eaddb6904aab89dca4d85099cb78"}, + {file = "orjson-3.10.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99b880d7e34542db89f48d14ddecbd26f06838b12427d5a25d71baceb5ba119d"}, + {file = "orjson-3.10.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2e5e176c994ce4bd434d7aafb9ecc893c15f347d3d2bbd8e7ce0b63071c52e25"}, + {file = "orjson-3.10.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b69a58a37dab856491bf2d3bbf259775fdce262b727f96aafbda359cb1d114d8"}, + {file = "orjson-3.10.3-cp39-none-win32.whl", hash = "sha256:b8d4d1a6868cde356f1402c8faeb50d62cee765a1f7ffcfd6de732ab0581e063"}, + {file = "orjson-3.10.3-cp39-none-win_amd64.whl", hash = "sha256:5102f50c5fc46d94f2033fe00d392588564378260d64377aec702f21a7a22912"}, + {file = "orjson-3.10.3.tar.gz", hash = "sha256:2b166507acae7ba2f7c315dcf185a9111ad5e992ac81f2d507aac39193c2c818"}, +] + +[[package]] +name = "overrides" +version = "7.7.0" +description = "A decorator to automatically detect mismatch when overriding a method." +optional = false +python-versions = ">=3.6" +files = [ + {file = "overrides-7.7.0-py3-none-any.whl", hash = "sha256:c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49"}, + {file = "overrides-7.7.0.tar.gz", hash = "sha256:55158fa3d93b98cc75299b1e67078ad9003ca27945c76162c1c0766d6f91820a"}, +] + [[package]] name = "packaging" -version = "24.0" +version = "23.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.7" files = [ - {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, - {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, ] [[package]] @@ -2123,6 +3405,17 @@ sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-d test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] xml = ["lxml (>=4.9.2)"] +[[package]] +name = "pandocfilters" +version = "1.5.1" +description = "Utilities for writing pandoc filters in python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pandocfilters-1.5.1-py2.py3-none-any.whl", hash = "sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc"}, + {file = "pandocfilters-1.5.1.tar.gz", hash = "sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e"}, +] + [[package]] name = "parso" version = "0.8.4" @@ -2138,6 +3431,24 @@ files = [ qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] testing = ["docopt", "pytest"] +[[package]] +name = "partd" +version = "1.4.2" +description = "Appendable key-value storage" +optional = false +python-versions = ">=3.9" +files = [ + {file = "partd-1.4.2-py3-none-any.whl", hash = "sha256:978e4ac767ec4ba5b86c6eaa52e5a2a3bc748a2ca839e8cc798f1cc6ce6efb0f"}, + {file = "partd-1.4.2.tar.gz", hash = "sha256:d022c33afbdc8405c226621b015e8067888173d85f7f5ecebb3cafed9a20f02c"}, +] + +[package.dependencies] +locket = "*" +toolz = "*" + +[package.extras] +complete = ["blosc", "numpy (>=1.20.0)", "pandas (>=1.3)", "pyzmq"] + [[package]] name = "pastel" version = "0.2.1" @@ -2205,6 +3516,17 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "ply" +version = "3.11" +description = "Python Lex & Yacc" +optional = false +python-versions = "*" +files = [ + {file = "ply-3.11-py2.py3-none-any.whl", hash = "sha256:096f9b8350b65ebd2fd1346b12452efe5b9607f7482813ffca50c22722a807ce"}, + {file = "ply-3.11.tar.gz", hash = "sha256:00c7c1aaa88358b9c765b6d3000c6eec0ba42abca5351b095321aef446081da3"}, +] + [[package]] name = "poethepoet" version = "0.25.1" @@ -2234,15 +3556,29 @@ files = [ {file = "pprintpp-0.4.0.tar.gz", hash = "sha256:ea826108e2c7f49dc6d66c752973c3fc9749142a798d6b254e1e301cfdbc6403"}, ] +[[package]] +name = "prometheus-client" +version = "0.20.0" +description = "Python client for the Prometheus monitoring system." +optional = false +python-versions = ">=3.8" +files = [ + {file = "prometheus_client-0.20.0-py3-none-any.whl", hash = "sha256:cde524a85bce83ca359cc837f28b8c0db5cac7aa653a588fd7e84ba061c329e7"}, + {file = "prometheus_client-0.20.0.tar.gz", hash = "sha256:287629d00b147a32dcb2be0b9df905da599b2d82f80377083ec8463309a4bb89"}, +] + +[package.extras] +twisted = ["twisted"] + [[package]] name = "prompt-toolkit" -version = "3.0.46" +version = "3.0.45" description = "Library for building powerful interactive command lines in Python" optional = false python-versions = ">=3.7.0" files = [ - {file = "prompt_toolkit-3.0.46-py3-none-any.whl", hash = "sha256:45abe60a8300f3c618b23c16c4bb98c6fc80af8ce8b17c7ae92db48db3ee63c1"}, - {file = "prompt_toolkit-3.0.46.tar.gz", hash = "sha256:869c50d682152336e23c4db7f74667639b5047494202ffe7670817053fd57795"}, + {file = "prompt_toolkit-3.0.45-py3-none-any.whl", hash = "sha256:a29b89160e494e3ea8622b09fa5897610b437884dcdcd054fdc1308883326c2a"}, + {file = "prompt_toolkit-3.0.45.tar.gz", hash = "sha256:07c60ee4ab7b7e90824b61afa840c8f5aad2d46b3e2e10acc33d8ecc94a49089"}, ] [package.dependencies] @@ -2285,6 +3621,34 @@ files = [ {file = "protobuf-4.25.3.tar.gz", hash = "sha256:25b5d0b42fd000320bd7830b349e3b696435f3b329810427a6bcce6a5492cc5c"}, ] +[[package]] +name = "psutil" +version = "5.9.8" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +files = [ + {file = "psutil-5.9.8-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:26bd09967ae00920df88e0352a91cff1a78f8d69b3ecabbfe733610c0af486c8"}, + {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:05806de88103b25903dff19bb6692bd2e714ccf9e668d050d144012055cbca73"}, + {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:611052c4bc70432ec770d5d54f64206aa7203a101ec273a0cd82418c86503bb7"}, + {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:50187900d73c1381ba1454cf40308c2bf6f34268518b3f36a9b663ca87e65e36"}, + {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:02615ed8c5ea222323408ceba16c60e99c3f91639b07da6373fb7e6539abc56d"}, + {file = "psutil-5.9.8-cp27-none-win32.whl", hash = "sha256:36f435891adb138ed3c9e58c6af3e2e6ca9ac2f365efe1f9cfef2794e6c93b4e"}, + {file = "psutil-5.9.8-cp27-none-win_amd64.whl", hash = "sha256:bd1184ceb3f87651a67b2708d4c3338e9b10c5df903f2e3776b62303b26cb631"}, + {file = "psutil-5.9.8-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:aee678c8720623dc456fa20659af736241f575d79429a0e5e9cf88ae0605cc81"}, + {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cb6403ce6d8e047495a701dc7c5bd788add903f8986d523e3e20b98b733e421"}, + {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d06016f7f8625a1825ba3732081d77c94589dca78b7a3fc072194851e88461a4"}, + {file = "psutil-5.9.8-cp36-cp36m-win32.whl", hash = "sha256:7d79560ad97af658a0f6adfef8b834b53f64746d45b403f225b85c5c2c140eee"}, + {file = "psutil-5.9.8-cp36-cp36m-win_amd64.whl", hash = "sha256:27cc40c3493bb10de1be4b3f07cae4c010ce715290a5be22b98493509c6299e2"}, + {file = "psutil-5.9.8-cp37-abi3-win32.whl", hash = "sha256:bc56c2a1b0d15aa3eaa5a60c9f3f8e3e565303b465dbf57a1b730e7a2b9844e0"}, + {file = "psutil-5.9.8-cp37-abi3-win_amd64.whl", hash = "sha256:8db4c1b57507eef143a15a6884ca10f7c73876cdf5d51e713151c1236a0e68cf"}, + {file = "psutil-5.9.8-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:d16bbddf0693323b8c6123dd804100241da461e41d6e332fb0ba6058f630f8c8"}, + {file = "psutil-5.9.8.tar.gz", hash = "sha256:6be126e3225486dff286a8fb9a06246a5253f4c7c53b475ea5f5ac934e64194c"}, +] + +[package.extras] +test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] + [[package]] name = "ptyprocess" version = "0.7.0" @@ -2337,13 +3701,13 @@ pyasn1 = ">=0.4.6,<0.7.0" [[package]] name = "pycnite" -version = "2024.5.27" +version = "2023.10.11" description = "Python bytecode utilities" optional = false python-versions = ">=3.8" files = [ - {file = "pycnite-2024.5.27-py3-none-any.whl", hash = "sha256:9274c95373663749323714bfc7e845d6ea0a793abc0d33dfc6932d660b7669a9"}, - {file = "pycnite-2024.5.27.tar.gz", hash = "sha256:825949037eba62a6c46a22c998ea8be83d0136ca5297d30ec6941b886af34628"}, + {file = "pycnite-2023.10.11-py3-none-any.whl", hash = "sha256:7d02eb0ec4b405d8812ce053434dacfc2335dcd458ab58a1a8bf64f72d40bd76"}, + {file = "pycnite-2023.10.11.tar.gz", hash = "sha256:ad8616982beecc39f2090999aa8fe0b044b1f6733ec39484cb5e0900b3c88aa1"}, ] [[package]] @@ -2365,21 +3729,32 @@ client = ["requests"] embedded = ["cozo-embedded (==0.7.6)"] pandas = ["ipython", "pandas"] +[[package]] +name = "pycparser" +version = "2.22" +description = "C parser in Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, + {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, +] + [[package]] name = "pydantic" -version = "2.7.3" +version = "2.7.2" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.7.3-py3-none-any.whl", hash = "sha256:ea91b002777bf643bb20dd717c028ec43216b24a6001a280f83877fd2655d0b4"}, - {file = "pydantic-2.7.3.tar.gz", hash = "sha256:c46c76a40bb1296728d7a8b99aa73dd70a48c3510111ff290034f860c99c419e"}, + {file = "pydantic-2.7.2-py3-none-any.whl", hash = "sha256:834ab954175f94e6e68258537dc49402c4a5e9d0409b9f1b86b7e934a8372de7"}, + {file = "pydantic-2.7.2.tar.gz", hash = "sha256:71b2945998f9c9b7919a45bde9a50397b289937d215ae141c1d0903ba7149fd7"}, ] [package.dependencies] annotated-types = ">=0.4.0" email-validator = {version = ">=2.0.0", optional = true, markers = "extra == \"email\""} -pydantic-core = "2.18.4" +pydantic-core = "2.18.3" typing-extensions = ">=4.6.1" [package.extras] @@ -2387,90 +3762,90 @@ email = ["email-validator (>=2.0.0)"] [[package]] name = "pydantic-core" -version = "2.18.4" +version = "2.18.3" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.18.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:f76d0ad001edd426b92233d45c746fd08f467d56100fd8f30e9ace4b005266e4"}, - {file = "pydantic_core-2.18.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:59ff3e89f4eaf14050c8022011862df275b552caef8082e37b542b066ce1ff26"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a55b5b16c839df1070bc113c1f7f94a0af4433fcfa1b41799ce7606e5c79ce0a"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4d0dcc59664fcb8974b356fe0a18a672d6d7cf9f54746c05f43275fc48636851"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8951eee36c57cd128f779e641e21eb40bc5073eb28b2d23f33eb0ef14ffb3f5d"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4701b19f7e3a06ea655513f7938de6f108123bf7c86bbebb1196eb9bd35cf724"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e00a3f196329e08e43d99b79b286d60ce46bed10f2280d25a1718399457e06be"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:97736815b9cc893b2b7f663628e63f436018b75f44854c8027040e05230eeddb"}, - {file = "pydantic_core-2.18.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6891a2ae0e8692679c07728819b6e2b822fb30ca7445f67bbf6509b25a96332c"}, - {file = "pydantic_core-2.18.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bc4ff9805858bd54d1a20efff925ccd89c9d2e7cf4986144b30802bf78091c3e"}, - {file = "pydantic_core-2.18.4-cp310-none-win32.whl", hash = "sha256:1b4de2e51bbcb61fdebd0ab86ef28062704f62c82bbf4addc4e37fa4b00b7cbc"}, - {file = "pydantic_core-2.18.4-cp310-none-win_amd64.whl", hash = "sha256:6a750aec7bf431517a9fd78cb93c97b9b0c496090fee84a47a0d23668976b4b0"}, - {file = "pydantic_core-2.18.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:942ba11e7dfb66dc70f9ae66b33452f51ac7bb90676da39a7345e99ffb55402d"}, - {file = "pydantic_core-2.18.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b2ebef0e0b4454320274f5e83a41844c63438fdc874ea40a8b5b4ecb7693f1c4"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a642295cd0c8df1b86fc3dced1d067874c353a188dc8e0f744626d49e9aa51c4"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f09baa656c904807e832cf9cce799c6460c450c4ad80803517032da0cd062e2"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:98906207f29bc2c459ff64fa007afd10a8c8ac080f7e4d5beff4c97086a3dabd"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19894b95aacfa98e7cb093cd7881a0c76f55731efad31073db4521e2b6ff5b7d"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fbbdc827fe5e42e4d196c746b890b3d72876bdbf160b0eafe9f0334525119c8"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f85d05aa0918283cf29a30b547b4df2fbb56b45b135f9e35b6807cb28bc47951"}, - {file = "pydantic_core-2.18.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e85637bc8fe81ddb73fda9e56bab24560bdddfa98aa64f87aaa4e4b6730c23d2"}, - {file = "pydantic_core-2.18.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2f5966897e5461f818e136b8451d0551a2e77259eb0f73a837027b47dc95dab9"}, - {file = "pydantic_core-2.18.4-cp311-none-win32.whl", hash = "sha256:44c7486a4228413c317952e9d89598bcdfb06399735e49e0f8df643e1ccd0558"}, - {file = "pydantic_core-2.18.4-cp311-none-win_amd64.whl", hash = "sha256:8a7164fe2005d03c64fd3b85649891cd4953a8de53107940bf272500ba8a788b"}, - {file = "pydantic_core-2.18.4-cp311-none-win_arm64.whl", hash = "sha256:4e99bc050fe65c450344421017f98298a97cefc18c53bb2f7b3531eb39bc7805"}, - {file = "pydantic_core-2.18.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:6f5c4d41b2771c730ea1c34e458e781b18cc668d194958e0112455fff4e402b2"}, - {file = "pydantic_core-2.18.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2fdf2156aa3d017fddf8aea5adfba9f777db1d6022d392b682d2a8329e087cef"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4748321b5078216070b151d5271ef3e7cc905ab170bbfd27d5c83ee3ec436695"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:847a35c4d58721c5dc3dba599878ebbdfd96784f3fb8bb2c356e123bdcd73f34"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c40d4eaad41f78e3bbda31b89edc46a3f3dc6e171bf0ecf097ff7a0ffff7cb1"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:21a5e440dbe315ab9825fcd459b8814bb92b27c974cbc23c3e8baa2b76890077"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01dd777215e2aa86dfd664daed5957704b769e726626393438f9c87690ce78c3"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4b06beb3b3f1479d32befd1f3079cc47b34fa2da62457cdf6c963393340b56e9"}, - {file = "pydantic_core-2.18.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:564d7922e4b13a16b98772441879fcdcbe82ff50daa622d681dd682175ea918c"}, - {file = "pydantic_core-2.18.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0eb2a4f660fcd8e2b1c90ad566db2b98d7f3f4717c64fe0a83e0adb39766d5b8"}, - {file = "pydantic_core-2.18.4-cp312-none-win32.whl", hash = "sha256:8b8bab4c97248095ae0c4455b5a1cd1cdd96e4e4769306ab19dda135ea4cdb07"}, - {file = "pydantic_core-2.18.4-cp312-none-win_amd64.whl", hash = "sha256:14601cdb733d741b8958224030e2bfe21a4a881fb3dd6fbb21f071cabd48fa0a"}, - {file = "pydantic_core-2.18.4-cp312-none-win_arm64.whl", hash = "sha256:c1322d7dd74713dcc157a2b7898a564ab091ca6c58302d5c7b4c07296e3fd00f"}, - {file = "pydantic_core-2.18.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:823be1deb01793da05ecb0484d6c9e20baebb39bd42b5d72636ae9cf8350dbd2"}, - {file = "pydantic_core-2.18.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ebef0dd9bf9b812bf75bda96743f2a6c5734a02092ae7f721c048d156d5fabae"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae1d6df168efb88d7d522664693607b80b4080be6750c913eefb77e34c12c71a"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f9899c94762343f2cc2fc64c13e7cae4c3cc65cdfc87dd810a31654c9b7358cc"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99457f184ad90235cfe8461c4d70ab7dd2680e28821c29eca00252ba90308c78"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18f469a3d2a2fdafe99296a87e8a4c37748b5080a26b806a707f25a902c040a8"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7cdf28938ac6b8b49ae5e92f2735056a7ba99c9b110a474473fd71185c1af5d"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:938cb21650855054dc54dfd9120a851c974f95450f00683399006aa6e8abb057"}, - {file = "pydantic_core-2.18.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:44cd83ab6a51da80fb5adbd9560e26018e2ac7826f9626bc06ca3dc074cd198b"}, - {file = "pydantic_core-2.18.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:972658f4a72d02b8abfa2581d92d59f59897d2e9f7e708fdabe922f9087773af"}, - {file = "pydantic_core-2.18.4-cp38-none-win32.whl", hash = "sha256:1d886dc848e60cb7666f771e406acae54ab279b9f1e4143babc9c2258213daa2"}, - {file = "pydantic_core-2.18.4-cp38-none-win_amd64.whl", hash = "sha256:bb4462bd43c2460774914b8525f79b00f8f407c945d50881568f294c1d9b4443"}, - {file = "pydantic_core-2.18.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:44a688331d4a4e2129140a8118479443bd6f1905231138971372fcde37e43528"}, - {file = "pydantic_core-2.18.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a2fdd81edd64342c85ac7cf2753ccae0b79bf2dfa063785503cb85a7d3593223"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:86110d7e1907ab36691f80b33eb2da87d780f4739ae773e5fc83fb272f88825f"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:46387e38bd641b3ee5ce247563b60c5ca098da9c56c75c157a05eaa0933ed154"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:123c3cec203e3f5ac7b000bd82235f1a3eced8665b63d18be751f115588fea30"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dc1803ac5c32ec324c5261c7209e8f8ce88e83254c4e1aebdc8b0a39f9ddb443"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53db086f9f6ab2b4061958d9c276d1dbe3690e8dd727d6abf2321d6cce37fa94"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:abc267fa9837245cc28ea6929f19fa335f3dc330a35d2e45509b6566dc18be23"}, - {file = "pydantic_core-2.18.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a0d829524aaefdebccb869eed855e2d04c21d2d7479b6cada7ace5448416597b"}, - {file = "pydantic_core-2.18.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:509daade3b8649f80d4e5ff21aa5673e4ebe58590b25fe42fac5f0f52c6f034a"}, - {file = "pydantic_core-2.18.4-cp39-none-win32.whl", hash = "sha256:ca26a1e73c48cfc54c4a76ff78df3727b9d9f4ccc8dbee4ae3f73306a591676d"}, - {file = "pydantic_core-2.18.4-cp39-none-win_amd64.whl", hash = "sha256:c67598100338d5d985db1b3d21f3619ef392e185e71b8d52bceacc4a7771ea7e"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:574d92eac874f7f4db0ca653514d823a0d22e2354359d0759e3f6a406db5d55d"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1f4d26ceb5eb9eed4af91bebeae4b06c3fb28966ca3a8fb765208cf6b51102ab"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77450e6d20016ec41f43ca4a6c63e9fdde03f0ae3fe90e7c27bdbeaece8b1ed4"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d323a01da91851a4f17bf592faf46149c9169d68430b3146dcba2bb5e5719abc"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:43d447dd2ae072a0065389092a231283f62d960030ecd27565672bd40746c507"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:578e24f761f3b425834f297b9935e1ce2e30f51400964ce4801002435a1b41ef"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:81b5efb2f126454586d0f40c4d834010979cb80785173d1586df845a632e4e6d"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ab86ce7c8f9bea87b9d12c7f0af71102acbf5ecbc66c17796cff45dae54ef9a5"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:90afc12421df2b1b4dcc975f814e21bc1754640d502a2fbcc6d41e77af5ec312"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:51991a89639a912c17bef4b45c87bd83593aee0437d8102556af4885811d59f5"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:293afe532740370aba8c060882f7d26cfd00c94cae32fd2e212a3a6e3b7bc15e"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b48ece5bde2e768197a2d0f6e925f9d7e3e826f0ad2271120f8144a9db18d5c8"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:eae237477a873ab46e8dd748e515c72c0c804fb380fbe6c85533c7de51f23a8f"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:834b5230b5dfc0c1ec37b2fda433b271cbbc0e507560b5d1588e2cc1148cf1ce"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e858ac0a25074ba4bce653f9b5d0a85b7456eaddadc0ce82d3878c22489fa4ee"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2fd41f6eff4c20778d717af1cc50eca52f5afe7805ee530a4fbd0bae284f16e9"}, - {file = "pydantic_core-2.18.4.tar.gz", hash = "sha256:ec3beeada09ff865c344ff3bc2f427f5e6c26401cc6113d77e372c3fdac73864"}, + {file = "pydantic_core-2.18.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:744697428fcdec6be5670460b578161d1ffe34743a5c15656be7ea82b008197c"}, + {file = "pydantic_core-2.18.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37b40c05ced1ba4218b14986fe6f283d22e1ae2ff4c8e28881a70fb81fbfcda7"}, + {file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:544a9a75622357076efb6b311983ff190fbfb3c12fc3a853122b34d3d358126c"}, + {file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e2e253af04ceaebde8eb201eb3f3e3e7e390f2d275a88300d6a1959d710539e2"}, + {file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:855ec66589c68aa367d989da5c4755bb74ee92ccad4fdb6af942c3612c067e34"}, + {file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d3e42bb54e7e9d72c13ce112e02eb1b3b55681ee948d748842171201a03a98a"}, + {file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6ac9ffccc9d2e69d9fba841441d4259cb668ac180e51b30d3632cd7abca2b9b"}, + {file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c56eca1686539fa0c9bda992e7bd6a37583f20083c37590413381acfc5f192d6"}, + {file = "pydantic_core-2.18.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:17954d784bf8abfc0ec2a633108207ebc4fa2df1a0e4c0c3ccbaa9bb01d2c426"}, + {file = "pydantic_core-2.18.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:98ed737567d8f2ecd54f7c8d4f8572ca7c7921ede93a2e52939416170d357812"}, + {file = "pydantic_core-2.18.3-cp310-none-win32.whl", hash = "sha256:9f9e04afebd3ed8c15d67a564ed0a34b54e52136c6d40d14c5547b238390e779"}, + {file = "pydantic_core-2.18.3-cp310-none-win_amd64.whl", hash = "sha256:45e4ffbae34f7ae30d0047697e724e534a7ec0a82ef9994b7913a412c21462a0"}, + {file = "pydantic_core-2.18.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:b9ebe8231726c49518b16b237b9fe0d7d361dd221302af511a83d4ada01183ab"}, + {file = "pydantic_core-2.18.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b8e20e15d18bf7dbb453be78a2d858f946f5cdf06c5072453dace00ab652e2b2"}, + {file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c0d9ff283cd3459fa0bf9b0256a2b6f01ac1ff9ffb034e24457b9035f75587cb"}, + {file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f7ef5f0ebb77ba24c9970da18b771711edc5feaf00c10b18461e0f5f5949231"}, + {file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73038d66614d2e5cde30435b5afdced2b473b4c77d4ca3a8624dd3e41a9c19be"}, + {file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6afd5c867a74c4d314c557b5ea9520183fadfbd1df4c2d6e09fd0d990ce412cd"}, + {file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd7df92f28d351bb9f12470f4c533cf03d1b52ec5a6e5c58c65b183055a60106"}, + {file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:80aea0ffeb1049336043d07799eace1c9602519fb3192916ff525b0287b2b1e4"}, + {file = "pydantic_core-2.18.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:aaee40f25bba38132e655ffa3d1998a6d576ba7cf81deff8bfa189fb43fd2bbe"}, + {file = "pydantic_core-2.18.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9128089da8f4fe73f7a91973895ebf2502539d627891a14034e45fb9e707e26d"}, + {file = "pydantic_core-2.18.3-cp311-none-win32.whl", hash = "sha256:fec02527e1e03257aa25b1a4dcbe697b40a22f1229f5d026503e8b7ff6d2eda7"}, + {file = "pydantic_core-2.18.3-cp311-none-win_amd64.whl", hash = "sha256:58ff8631dbab6c7c982e6425da8347108449321f61fe427c52ddfadd66642af7"}, + {file = "pydantic_core-2.18.3-cp311-none-win_arm64.whl", hash = "sha256:3fc1c7f67f34c6c2ef9c213e0f2a351797cda98249d9ca56a70ce4ebcaba45f4"}, + {file = "pydantic_core-2.18.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f0928cde2ae416a2d1ebe6dee324709c6f73e93494d8c7aea92df99aab1fc40f"}, + {file = "pydantic_core-2.18.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0bee9bb305a562f8b9271855afb6ce00223f545de3d68560b3c1649c7c5295e9"}, + {file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e862823be114387257dacbfa7d78547165a85d7add33b446ca4f4fae92c7ff5c"}, + {file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6a36f78674cbddc165abab0df961b5f96b14461d05feec5e1f78da58808b97e7"}, + {file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba905d184f62e7ddbb7a5a751d8a5c805463511c7b08d1aca4a3e8c11f2e5048"}, + {file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7fdd362f6a586e681ff86550b2379e532fee63c52def1c666887956748eaa326"}, + {file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24b214b7ee3bd3b865e963dbed0f8bc5375f49449d70e8d407b567af3222aae4"}, + {file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:691018785779766127f531674fa82bb368df5b36b461622b12e176c18e119022"}, + {file = "pydantic_core-2.18.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:60e4c625e6f7155d7d0dcac151edf5858102bc61bf959d04469ca6ee4e8381bd"}, + {file = "pydantic_core-2.18.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a4e651e47d981c1b701dcc74ab8fec5a60a5b004650416b4abbef13db23bc7be"}, + {file = "pydantic_core-2.18.3-cp312-none-win32.whl", hash = "sha256:ffecbb5edb7f5ffae13599aec33b735e9e4c7676ca1633c60f2c606beb17efc5"}, + {file = "pydantic_core-2.18.3-cp312-none-win_amd64.whl", hash = "sha256:2c8333f6e934733483c7eddffdb094c143b9463d2af7e6bd85ebcb2d4a1b82c6"}, + {file = "pydantic_core-2.18.3-cp312-none-win_arm64.whl", hash = "sha256:7a20dded653e516a4655f4c98e97ccafb13753987434fe7cf044aa25f5b7d417"}, + {file = "pydantic_core-2.18.3-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:eecf63195be644b0396f972c82598cd15693550f0ff236dcf7ab92e2eb6d3522"}, + {file = "pydantic_core-2.18.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2c44efdd3b6125419c28821590d7ec891c9cb0dff33a7a78d9d5c8b6f66b9702"}, + {file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e59fca51ffbdd1638b3856779342ed69bcecb8484c1d4b8bdb237d0eb5a45e2"}, + {file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:70cf099197d6b98953468461d753563b28e73cf1eade2ffe069675d2657ed1d5"}, + {file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:63081a49dddc6124754b32a3774331467bfc3d2bd5ff8f10df36a95602560361"}, + {file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:370059b7883485c9edb9655355ff46d912f4b03b009d929220d9294c7fd9fd60"}, + {file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a64faeedfd8254f05f5cf6fc755023a7e1606af3959cfc1a9285744cc711044"}, + {file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19d2e725de0f90d8671f89e420d36c3dd97639b98145e42fcc0e1f6d492a46dc"}, + {file = "pydantic_core-2.18.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:67bc078025d70ec5aefe6200ef094576c9d86bd36982df1301c758a9fff7d7f4"}, + {file = "pydantic_core-2.18.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:adf952c3f4100e203cbaf8e0c907c835d3e28f9041474e52b651761dc248a3c0"}, + {file = "pydantic_core-2.18.3-cp38-none-win32.whl", hash = "sha256:9a46795b1f3beb167eaee91736d5d17ac3a994bf2215a996aed825a45f897558"}, + {file = "pydantic_core-2.18.3-cp38-none-win_amd64.whl", hash = "sha256:200ad4e3133cb99ed82342a101a5abf3d924722e71cd581cc113fe828f727fbc"}, + {file = "pydantic_core-2.18.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:304378b7bf92206036c8ddd83a2ba7b7d1a5b425acafff637172a3aa72ad7083"}, + {file = "pydantic_core-2.18.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c826870b277143e701c9ccf34ebc33ddb4d072612683a044e7cce2d52f6c3fef"}, + {file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e201935d282707394f3668380e41ccf25b5794d1b131cdd96b07f615a33ca4b1"}, + {file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5560dda746c44b48bf82b3d191d74fe8efc5686a9ef18e69bdabccbbb9ad9442"}, + {file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6b32c2a1f8032570842257e4c19288eba9a2bba4712af542327de9a1204faff8"}, + {file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:929c24e9dea3990bc8bcd27c5f2d3916c0c86f5511d2caa69e0d5290115344a9"}, + {file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1a8376fef60790152564b0eab376b3e23dd6e54f29d84aad46f7b264ecca943"}, + {file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dccf3ef1400390ddd1fb55bf0632209d39140552d068ee5ac45553b556780e06"}, + {file = "pydantic_core-2.18.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:41dbdcb0c7252b58fa931fec47937edb422c9cb22528f41cb8963665c372caf6"}, + {file = "pydantic_core-2.18.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:666e45cf071669fde468886654742fa10b0e74cd0fa0430a46ba6056b24fb0af"}, + {file = "pydantic_core-2.18.3-cp39-none-win32.whl", hash = "sha256:f9c08cabff68704a1b4667d33f534d544b8a07b8e5d039c37067fceb18789e78"}, + {file = "pydantic_core-2.18.3-cp39-none-win_amd64.whl", hash = "sha256:4afa5f5973e8572b5c0dcb4e2d4fda7890e7cd63329bd5cc3263a25c92ef0026"}, + {file = "pydantic_core-2.18.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:77319771a026f7c7d29c6ebc623de889e9563b7087911b46fd06c044a12aa5e9"}, + {file = "pydantic_core-2.18.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:df11fa992e9f576473038510d66dd305bcd51d7dd508c163a8c8fe148454e059"}, + {file = "pydantic_core-2.18.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d531076bdfb65af593326ffd567e6ab3da145020dafb9187a1d131064a55f97c"}, + {file = "pydantic_core-2.18.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d33ce258e4e6e6038f2b9e8b8a631d17d017567db43483314993b3ca345dcbbb"}, + {file = "pydantic_core-2.18.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1f9cd7f5635b719939019be9bda47ecb56e165e51dd26c9a217a433e3d0d59a9"}, + {file = "pydantic_core-2.18.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:cd4a032bb65cc132cae1fe3e52877daecc2097965cd3914e44fbd12b00dae7c5"}, + {file = "pydantic_core-2.18.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f2718430098bcdf60402136c845e4126a189959d103900ebabb6774a5d9fdb"}, + {file = "pydantic_core-2.18.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c0037a92cf0c580ed14e10953cdd26528e8796307bb8bb312dc65f71547df04d"}, + {file = "pydantic_core-2.18.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b95a0972fac2b1ff3c94629fc9081b16371dad870959f1408cc33b2f78ad347a"}, + {file = "pydantic_core-2.18.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a62e437d687cc148381bdd5f51e3e81f5b20a735c55f690c5be94e05da2b0d5c"}, + {file = "pydantic_core-2.18.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b367a73a414bbb08507da102dc2cde0fa7afe57d09b3240ce82a16d608a7679c"}, + {file = "pydantic_core-2.18.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ecce4b2360aa3f008da3327d652e74a0e743908eac306198b47e1c58b03dd2b"}, + {file = "pydantic_core-2.18.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bd4435b8d83f0c9561a2a9585b1de78f1abb17cb0cef5f39bf6a4b47d19bafe3"}, + {file = "pydantic_core-2.18.3-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:616221a6d473c5b9aa83fa8982745441f6a4a62a66436be9445c65f241b86c94"}, + {file = "pydantic_core-2.18.3-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:7e6382ce89a92bc1d0c0c5edd51e931432202b9080dc921d8d003e616402efd1"}, + {file = "pydantic_core-2.18.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ff58f379345603d940e461eae474b6bbb6dab66ed9a851ecd3cb3709bf4dcf6a"}, + {file = "pydantic_core-2.18.3.tar.gz", hash = "sha256:432e999088d85c8f36b9a3f769a8e2b57aabd817bbb729a90d1fe7f18f6f1f39"}, ] [package.dependencies] @@ -2568,6 +3943,17 @@ files = [ [package.extras] cli = ["click (>=5.0)"] +[[package]] +name = "python-json-logger" +version = "2.0.7" +description = "A python library adding a json log formatter" +optional = false +python-versions = ">=3.6" +files = [ + {file = "python-json-logger-2.0.7.tar.gz", hash = "sha256:23e7ec02d34237c5aa1e29a070193a4ea87583bb4e7f8fd06d3de8264c4b2e1c"}, + {file = "python_json_logger-2.0.7-py3-none-any.whl", hash = "sha256:f380b826a991ebbe3de4d897aeec42760035ac760345e57b812938dc8b35e2bd"}, +] + [[package]] name = "pytype" version = "2024.4.11" @@ -2616,6 +4002,44 @@ files = [ {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, ] +[[package]] +name = "pywin32" +version = "306" +description = "Python for Window Extensions" +optional = false +python-versions = "*" +files = [ + {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, + {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, + {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"}, + {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"}, + {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"}, + {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"}, + {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"}, + {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"}, + {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"}, + {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"}, + {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"}, + {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"}, + {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"}, + {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, +] + +[[package]] +name = "pywinpty" +version = "2.0.13" +description = "Pseudo terminal support for Windows from Python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pywinpty-2.0.13-cp310-none-win_amd64.whl", hash = "sha256:697bff211fb5a6508fee2dc6ff174ce03f34a9a233df9d8b5fe9c8ce4d5eaf56"}, + {file = "pywinpty-2.0.13-cp311-none-win_amd64.whl", hash = "sha256:b96fb14698db1284db84ca38c79f15b4cfdc3172065b5137383910567591fa99"}, + {file = "pywinpty-2.0.13-cp312-none-win_amd64.whl", hash = "sha256:2fd876b82ca750bb1333236ce98488c1be96b08f4f7647cfdf4129dfad83c2d4"}, + {file = "pywinpty-2.0.13-cp38-none-win_amd64.whl", hash = "sha256:61d420c2116c0212808d31625611b51caf621fe67f8a6377e2e8b617ea1c1f7d"}, + {file = "pywinpty-2.0.13-cp39-none-win_amd64.whl", hash = "sha256:71cb613a9ee24174730ac7ae439fd179ca34ccb8c5349e8d7b72ab5dea2c6f4b"}, + {file = "pywinpty-2.0.13.tar.gz", hash = "sha256:c34e32351a3313ddd0d7da23d27f835c860d32fe4ac814d372a3ea9594f41dde"}, +] + [[package]] name = "pyyaml" version = "6.0.1" @@ -2641,7 +4065,6 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -2676,6 +4099,106 @@ files = [ {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, ] +[[package]] +name = "pyzmq" +version = "26.0.3" +description = "Python bindings for 0MQ" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pyzmq-26.0.3-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:44dd6fc3034f1eaa72ece33588867df9e006a7303725a12d64c3dff92330f625"}, + {file = "pyzmq-26.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:acb704195a71ac5ea5ecf2811c9ee19ecdc62b91878528302dd0be1b9451cc90"}, + {file = "pyzmq-26.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dbb9c997932473a27afa93954bb77a9f9b786b4ccf718d903f35da3232317de"}, + {file = "pyzmq-26.0.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6bcb34f869d431799c3ee7d516554797f7760cb2198ecaa89c3f176f72d062be"}, + {file = "pyzmq-26.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38ece17ec5f20d7d9b442e5174ae9f020365d01ba7c112205a4d59cf19dc38ee"}, + {file = "pyzmq-26.0.3-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:ba6e5e6588e49139a0979d03a7deb9c734bde647b9a8808f26acf9c547cab1bf"}, + {file = "pyzmq-26.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3bf8b000a4e2967e6dfdd8656cd0757d18c7e5ce3d16339e550bd462f4857e59"}, + {file = "pyzmq-26.0.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:2136f64fbb86451dbbf70223635a468272dd20075f988a102bf8a3f194a411dc"}, + {file = "pyzmq-26.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e8918973fbd34e7814f59143c5f600ecd38b8038161239fd1a3d33d5817a38b8"}, + {file = "pyzmq-26.0.3-cp310-cp310-win32.whl", hash = "sha256:0aaf982e68a7ac284377d051c742610220fd06d330dcd4c4dbb4cdd77c22a537"}, + {file = "pyzmq-26.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:f1a9b7d00fdf60b4039f4455afd031fe85ee8305b019334b72dcf73c567edc47"}, + {file = "pyzmq-26.0.3-cp310-cp310-win_arm64.whl", hash = "sha256:80b12f25d805a919d53efc0a5ad7c0c0326f13b4eae981a5d7b7cc343318ebb7"}, + {file = "pyzmq-26.0.3-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:a72a84570f84c374b4c287183debc776dc319d3e8ce6b6a0041ce2e400de3f32"}, + {file = "pyzmq-26.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7ca684ee649b55fd8f378127ac8462fb6c85f251c2fb027eb3c887e8ee347bcd"}, + {file = "pyzmq-26.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e222562dc0f38571c8b1ffdae9d7adb866363134299264a1958d077800b193b7"}, + {file = "pyzmq-26.0.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f17cde1db0754c35a91ac00b22b25c11da6eec5746431d6e5092f0cd31a3fea9"}, + {file = "pyzmq-26.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b7c0c0b3244bb2275abe255d4a30c050d541c6cb18b870975553f1fb6f37527"}, + {file = "pyzmq-26.0.3-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:ac97a21de3712afe6a6c071abfad40a6224fd14fa6ff0ff8d0c6e6cd4e2f807a"}, + {file = "pyzmq-26.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:88b88282e55fa39dd556d7fc04160bcf39dea015f78e0cecec8ff4f06c1fc2b5"}, + {file = "pyzmq-26.0.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:72b67f966b57dbd18dcc7efbc1c7fc9f5f983e572db1877081f075004614fcdd"}, + {file = "pyzmq-26.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f4b6cecbbf3b7380f3b61de3a7b93cb721125dc125c854c14ddc91225ba52f83"}, + {file = "pyzmq-26.0.3-cp311-cp311-win32.whl", hash = "sha256:eed56b6a39216d31ff8cd2f1d048b5bf1700e4b32a01b14379c3b6dde9ce3aa3"}, + {file = "pyzmq-26.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:3191d312c73e3cfd0f0afdf51df8405aafeb0bad71e7ed8f68b24b63c4f36500"}, + {file = "pyzmq-26.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:b6907da3017ef55139cf0e417c5123a84c7332520e73a6902ff1f79046cd3b94"}, + {file = "pyzmq-26.0.3-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:068ca17214038ae986d68f4a7021f97e187ed278ab6dccb79f837d765a54d753"}, + {file = "pyzmq-26.0.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:7821d44fe07335bea256b9f1f41474a642ca55fa671dfd9f00af8d68a920c2d4"}, + {file = "pyzmq-26.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eeb438a26d87c123bb318e5f2b3d86a36060b01f22fbdffd8cf247d52f7c9a2b"}, + {file = "pyzmq-26.0.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:69ea9d6d9baa25a4dc9cef5e2b77b8537827b122214f210dd925132e34ae9b12"}, + {file = "pyzmq-26.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7daa3e1369355766dea11f1d8ef829905c3b9da886ea3152788dc25ee6079e02"}, + {file = "pyzmq-26.0.3-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:6ca7a9a06b52d0e38ccf6bca1aeff7be178917893f3883f37b75589d42c4ac20"}, + {file = "pyzmq-26.0.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1b7d0e124948daa4d9686d421ef5087c0516bc6179fdcf8828b8444f8e461a77"}, + {file = "pyzmq-26.0.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:e746524418b70f38550f2190eeee834db8850088c834d4c8406fbb9bc1ae10b2"}, + {file = "pyzmq-26.0.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:6b3146f9ae6af82c47a5282ac8803523d381b3b21caeae0327ed2f7ecb718798"}, + {file = "pyzmq-26.0.3-cp312-cp312-win32.whl", hash = "sha256:2b291d1230845871c00c8462c50565a9cd6026fe1228e77ca934470bb7d70ea0"}, + {file = "pyzmq-26.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:926838a535c2c1ea21c903f909a9a54e675c2126728c21381a94ddf37c3cbddf"}, + {file = "pyzmq-26.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:5bf6c237f8c681dfb91b17f8435b2735951f0d1fad10cc5dfd96db110243370b"}, + {file = "pyzmq-26.0.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c0991f5a96a8e620f7691e61178cd8f457b49e17b7d9cfa2067e2a0a89fc1d5"}, + {file = "pyzmq-26.0.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:dbf012d8fcb9f2cf0643b65df3b355fdd74fc0035d70bb5c845e9e30a3a4654b"}, + {file = "pyzmq-26.0.3-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:01fbfbeb8249a68d257f601deb50c70c929dc2dfe683b754659569e502fbd3aa"}, + {file = "pyzmq-26.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c8eb19abe87029c18f226d42b8a2c9efdd139d08f8bf6e085dd9075446db450"}, + {file = "pyzmq-26.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:5344b896e79800af86ad643408ca9aa303a017f6ebff8cee5a3163c1e9aec987"}, + {file = "pyzmq-26.0.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:204e0f176fd1d067671157d049466869b3ae1fc51e354708b0dc41cf94e23a3a"}, + {file = "pyzmq-26.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a42db008d58530efa3b881eeee4991146de0b790e095f7ae43ba5cc612decbc5"}, + {file = "pyzmq-26.0.3-cp37-cp37m-win32.whl", hash = "sha256:8d7a498671ca87e32b54cb47c82a92b40130a26c5197d392720a1bce1b3c77cf"}, + {file = "pyzmq-26.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:3b4032a96410bdc760061b14ed6a33613ffb7f702181ba999df5d16fb96ba16a"}, + {file = "pyzmq-26.0.3-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:2cc4e280098c1b192c42a849de8de2c8e0f3a84086a76ec5b07bfee29bda7d18"}, + {file = "pyzmq-26.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5bde86a2ed3ce587fa2b207424ce15b9a83a9fa14422dcc1c5356a13aed3df9d"}, + {file = "pyzmq-26.0.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:34106f68e20e6ff253c9f596ea50397dbd8699828d55e8fa18bd4323d8d966e6"}, + {file = "pyzmq-26.0.3-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ebbbd0e728af5db9b04e56389e2299a57ea8b9dd15c9759153ee2455b32be6ad"}, + {file = "pyzmq-26.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6b1d1c631e5940cac5a0b22c5379c86e8df6a4ec277c7a856b714021ab6cfad"}, + {file = "pyzmq-26.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e891ce81edd463b3b4c3b885c5603c00141151dd9c6936d98a680c8c72fe5c67"}, + {file = "pyzmq-26.0.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9b273ecfbc590a1b98f014ae41e5cf723932f3b53ba9367cfb676f838038b32c"}, + {file = "pyzmq-26.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b32bff85fb02a75ea0b68f21e2412255b5731f3f389ed9aecc13a6752f58ac97"}, + {file = "pyzmq-26.0.3-cp38-cp38-win32.whl", hash = "sha256:f6c21c00478a7bea93caaaef9e7629145d4153b15a8653e8bb4609d4bc70dbfc"}, + {file = "pyzmq-26.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:3401613148d93ef0fd9aabdbddb212de3db7a4475367f49f590c837355343972"}, + {file = "pyzmq-26.0.3-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:2ed8357f4c6e0daa4f3baf31832df8a33334e0fe5b020a61bc8b345a3db7a606"}, + {file = "pyzmq-26.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c1c8f2a2ca45292084c75bb6d3a25545cff0ed931ed228d3a1810ae3758f975f"}, + {file = "pyzmq-26.0.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b63731993cdddcc8e087c64e9cf003f909262b359110070183d7f3025d1c56b5"}, + {file = "pyzmq-26.0.3-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b3cd31f859b662ac5d7f4226ec7d8bd60384fa037fc02aee6ff0b53ba29a3ba8"}, + {file = "pyzmq-26.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:115f8359402fa527cf47708d6f8a0f8234f0e9ca0cab7c18c9c189c194dbf620"}, + {file = "pyzmq-26.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:715bdf952b9533ba13dfcf1f431a8f49e63cecc31d91d007bc1deb914f47d0e4"}, + {file = "pyzmq-26.0.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e1258c639e00bf5e8a522fec6c3eaa3e30cf1c23a2f21a586be7e04d50c9acab"}, + {file = "pyzmq-26.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:15c59e780be8f30a60816a9adab900c12a58d79c1ac742b4a8df044ab2a6d920"}, + {file = "pyzmq-26.0.3-cp39-cp39-win32.whl", hash = "sha256:d0cdde3c78d8ab5b46595054e5def32a755fc028685add5ddc7403e9f6de9879"}, + {file = "pyzmq-26.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:ce828058d482ef860746bf532822842e0ff484e27f540ef5c813d516dd8896d2"}, + {file = "pyzmq-26.0.3-cp39-cp39-win_arm64.whl", hash = "sha256:788f15721c64109cf720791714dc14afd0f449d63f3a5487724f024345067381"}, + {file = "pyzmq-26.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2c18645ef6294d99b256806e34653e86236eb266278c8ec8112622b61db255de"}, + {file = "pyzmq-26.0.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7e6bc96ebe49604df3ec2c6389cc3876cabe475e6bfc84ced1bf4e630662cb35"}, + {file = "pyzmq-26.0.3-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:971e8990c5cc4ddcff26e149398fc7b0f6a042306e82500f5e8db3b10ce69f84"}, + {file = "pyzmq-26.0.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8416c23161abd94cc7da80c734ad7c9f5dbebdadfdaa77dad78244457448223"}, + {file = "pyzmq-26.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:082a2988364b60bb5de809373098361cf1dbb239623e39e46cb18bc035ed9c0c"}, + {file = "pyzmq-26.0.3-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d57dfbf9737763b3a60d26e6800e02e04284926329aee8fb01049635e957fe81"}, + {file = "pyzmq-26.0.3-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:77a85dca4c2430ac04dc2a2185c2deb3858a34fe7f403d0a946fa56970cf60a1"}, + {file = "pyzmq-26.0.3-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4c82a6d952a1d555bf4be42b6532927d2a5686dd3c3e280e5f63225ab47ac1f5"}, + {file = "pyzmq-26.0.3-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4496b1282c70c442809fc1b151977c3d967bfb33e4e17cedbf226d97de18f709"}, + {file = "pyzmq-26.0.3-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:e4946d6bdb7ba972dfda282f9127e5756d4f299028b1566d1245fa0d438847e6"}, + {file = "pyzmq-26.0.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:03c0ae165e700364b266876d712acb1ac02693acd920afa67da2ebb91a0b3c09"}, + {file = "pyzmq-26.0.3-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:3e3070e680f79887d60feeda051a58d0ac36622e1759f305a41059eff62c6da7"}, + {file = "pyzmq-26.0.3-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6ca08b840fe95d1c2bd9ab92dac5685f949fc6f9ae820ec16193e5ddf603c3b2"}, + {file = "pyzmq-26.0.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e76654e9dbfb835b3518f9938e565c7806976c07b37c33526b574cc1a1050480"}, + {file = "pyzmq-26.0.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:871587bdadd1075b112e697173e946a07d722459d20716ceb3d1bd6c64bd08ce"}, + {file = "pyzmq-26.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d0a2d1bd63a4ad79483049b26514e70fa618ce6115220da9efdff63688808b17"}, + {file = "pyzmq-26.0.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0270b49b6847f0d106d64b5086e9ad5dc8a902413b5dbbb15d12b60f9c1747a4"}, + {file = "pyzmq-26.0.3-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:703c60b9910488d3d0954ca585c34f541e506a091a41930e663a098d3b794c67"}, + {file = "pyzmq-26.0.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:74423631b6be371edfbf7eabb02ab995c2563fee60a80a30829176842e71722a"}, + {file = "pyzmq-26.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4adfbb5451196842a88fda3612e2c0414134874bffb1c2ce83ab4242ec9e027d"}, + {file = "pyzmq-26.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3516119f4f9b8671083a70b6afaa0a070f5683e431ab3dc26e9215620d7ca1ad"}, + {file = "pyzmq-26.0.3.tar.gz", hash = "sha256:dba7d9f2e047dfa2bca3b01f4f84aa5246725203d6284e3790f2ca15fba6b40a"}, +] + +[package.dependencies] +cffi = {version = "*", markers = "implementation_name == \"pypy\""} + [[package]] name = "referencing" version = "0.35.1" @@ -2800,6 +4323,31 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] +[[package]] +name = "rfc3339-validator" +version = "0.1.4" +description = "A pure python RFC3339 validator" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa"}, + {file = "rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b"}, +] + +[package.dependencies] +six = "*" + +[[package]] +name = "rfc3986-validator" +version = "0.1.1" +description = "Pure python rfc3986 validator" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9"}, + {file = "rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055"}, +] + [[package]] name = "rich" version = "13.7.1" @@ -3088,6 +4636,22 @@ tensorflow = ["safetensors[numpy]", "tensorflow (>=2.11.0)"] testing = ["h5py (>=3.7.0)", "huggingface-hub (>=0.12.1)", "hypothesis (>=6.70.2)", "pytest (>=7.2.0)", "pytest-benchmark (>=4.0.0)", "safetensors[numpy]", "setuptools-rust (>=1.5.2)"] torch = ["safetensors[numpy]", "torch (>=1.10)"] +[[package]] +name = "send2trash" +version = "1.8.3" +description = "Send file to trash natively under Mac OS X, Windows and Linux" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "Send2Trash-1.8.3-py3-none-any.whl", hash = "sha256:0c31227e0bd08961c7665474a3d1ef7193929fedda4233843689baa056be46c9"}, + {file = "Send2Trash-1.8.3.tar.gz", hash = "sha256:b18e7a3966d99871aefeb00cfbcfdced55ce4871194810fc71f4aa484b953abf"}, +] + +[package.extras] +nativelib = ["pyobjc-framework-Cocoa", "pywin32"] +objc = ["pyobjc-framework-Cocoa"] +win32 = ["pywin32"] + [[package]] name = "sentry-sdk" version = "1.45.0" @@ -3226,6 +4790,115 @@ files = [ {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, ] +[[package]] +name = "sortedcontainers" +version = "2.4.0" +description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" +optional = false +python-versions = "*" +files = [ + {file = "sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0"}, + {file = "sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88"}, +] + +[[package]] +name = "soupsieve" +version = "2.5" +description = "A modern CSS selector implementation for Beautiful Soup." +optional = false +python-versions = ">=3.8" +files = [ + {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"}, + {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, +] + +[[package]] +name = "sqlalchemy" +version = "2.0.30" +description = "Database Abstraction Library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "SQLAlchemy-2.0.30-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3b48154678e76445c7ded1896715ce05319f74b1e73cf82d4f8b59b46e9c0ddc"}, + {file = "SQLAlchemy-2.0.30-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2753743c2afd061bb95a61a51bbb6a1a11ac1c44292fad898f10c9839a7f75b2"}, + {file = "SQLAlchemy-2.0.30-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7bfc726d167f425d4c16269a9a10fe8630ff6d14b683d588044dcef2d0f6be7"}, + {file = "SQLAlchemy-2.0.30-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4f61ada6979223013d9ab83a3ed003ded6959eae37d0d685db2c147e9143797"}, + {file = "SQLAlchemy-2.0.30-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3a365eda439b7a00732638f11072907c1bc8e351c7665e7e5da91b169af794af"}, + {file = "SQLAlchemy-2.0.30-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bba002a9447b291548e8d66fd8c96a6a7ed4f2def0bb155f4f0a1309fd2735d5"}, + {file = "SQLAlchemy-2.0.30-cp310-cp310-win32.whl", hash = "sha256:0138c5c16be3600923fa2169532205d18891b28afa817cb49b50e08f62198bb8"}, + {file = "SQLAlchemy-2.0.30-cp310-cp310-win_amd64.whl", hash = "sha256:99650e9f4cf3ad0d409fed3eec4f071fadd032e9a5edc7270cd646a26446feeb"}, + {file = "SQLAlchemy-2.0.30-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:955991a09f0992c68a499791a753523f50f71a6885531568404fa0f231832aa0"}, + {file = "SQLAlchemy-2.0.30-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f69e4c756ee2686767eb80f94c0125c8b0a0b87ede03eacc5c8ae3b54b99dc46"}, + {file = "SQLAlchemy-2.0.30-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69c9db1ce00e59e8dd09d7bae852a9add716efdc070a3e2068377e6ff0d6fdaa"}, + {file = "SQLAlchemy-2.0.30-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1429a4b0f709f19ff3b0cf13675b2b9bfa8a7e79990003207a011c0db880a13"}, + {file = "SQLAlchemy-2.0.30-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:efedba7e13aa9a6c8407c48facfdfa108a5a4128e35f4c68f20c3407e4376aa9"}, + {file = "SQLAlchemy-2.0.30-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:16863e2b132b761891d6c49f0a0f70030e0bcac4fd208117f6b7e053e68668d0"}, + {file = "SQLAlchemy-2.0.30-cp311-cp311-win32.whl", hash = "sha256:2ecabd9ccaa6e914e3dbb2aa46b76dede7eadc8cbf1b8083c94d936bcd5ffb49"}, + {file = "SQLAlchemy-2.0.30-cp311-cp311-win_amd64.whl", hash = "sha256:0b3f4c438e37d22b83e640f825ef0f37b95db9aa2d68203f2c9549375d0b2260"}, + {file = "SQLAlchemy-2.0.30-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5a79d65395ac5e6b0c2890935bad892eabb911c4aa8e8015067ddb37eea3d56c"}, + {file = "SQLAlchemy-2.0.30-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9a5baf9267b752390252889f0c802ea13b52dfee5e369527da229189b8bd592e"}, + {file = "SQLAlchemy-2.0.30-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cb5a646930c5123f8461f6468901573f334c2c63c795b9af350063a736d0134"}, + {file = "SQLAlchemy-2.0.30-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:296230899df0b77dec4eb799bcea6fbe39a43707ce7bb166519c97b583cfcab3"}, + {file = "SQLAlchemy-2.0.30-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c62d401223f468eb4da32627bffc0c78ed516b03bb8a34a58be54d618b74d472"}, + {file = "SQLAlchemy-2.0.30-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3b69e934f0f2b677ec111b4d83f92dc1a3210a779f69bf905273192cf4ed433e"}, + {file = "SQLAlchemy-2.0.30-cp312-cp312-win32.whl", hash = "sha256:77d2edb1f54aff37e3318f611637171e8ec71472f1fdc7348b41dcb226f93d90"}, + {file = "SQLAlchemy-2.0.30-cp312-cp312-win_amd64.whl", hash = "sha256:b6c7ec2b1f4969fc19b65b7059ed00497e25f54069407a8701091beb69e591a5"}, + {file = "SQLAlchemy-2.0.30-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5a8e3b0a7e09e94be7510d1661339d6b52daf202ed2f5b1f9f48ea34ee6f2d57"}, + {file = "SQLAlchemy-2.0.30-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b60203c63e8f984df92035610c5fb76d941254cf5d19751faab7d33b21e5ddc0"}, + {file = "SQLAlchemy-2.0.30-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1dc3eabd8c0232ee8387fbe03e0a62220a6f089e278b1f0aaf5e2d6210741ad"}, + {file = "SQLAlchemy-2.0.30-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:40ad017c672c00b9b663fcfcd5f0864a0a97828e2ee7ab0c140dc84058d194cf"}, + {file = "SQLAlchemy-2.0.30-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e42203d8d20dc704604862977b1470a122e4892791fe3ed165f041e4bf447a1b"}, + {file = "SQLAlchemy-2.0.30-cp37-cp37m-win32.whl", hash = "sha256:2a4f4da89c74435f2bc61878cd08f3646b699e7d2eba97144030d1be44e27584"}, + {file = "SQLAlchemy-2.0.30-cp37-cp37m-win_amd64.whl", hash = "sha256:b6bf767d14b77f6a18b6982cbbf29d71bede087edae495d11ab358280f304d8e"}, + {file = "SQLAlchemy-2.0.30-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bc0c53579650a891f9b83fa3cecd4e00218e071d0ba00c4890f5be0c34887ed3"}, + {file = "SQLAlchemy-2.0.30-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:311710f9a2ee235f1403537b10c7687214bb1f2b9ebb52702c5aa4a77f0b3af7"}, + {file = "SQLAlchemy-2.0.30-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:408f8b0e2c04677e9c93f40eef3ab22f550fecb3011b187f66a096395ff3d9fd"}, + {file = "SQLAlchemy-2.0.30-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37a4b4fb0dd4d2669070fb05b8b8824afd0af57587393015baee1cf9890242d9"}, + {file = "SQLAlchemy-2.0.30-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a943d297126c9230719c27fcbbeab57ecd5d15b0bd6bfd26e91bfcfe64220621"}, + {file = "SQLAlchemy-2.0.30-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0a089e218654e740a41388893e090d2e2c22c29028c9d1353feb38638820bbeb"}, + {file = "SQLAlchemy-2.0.30-cp38-cp38-win32.whl", hash = "sha256:fa561138a64f949f3e889eb9ab8c58e1504ab351d6cf55259dc4c248eaa19da6"}, + {file = "SQLAlchemy-2.0.30-cp38-cp38-win_amd64.whl", hash = "sha256:7d74336c65705b986d12a7e337ba27ab2b9d819993851b140efdf029248e818e"}, + {file = "SQLAlchemy-2.0.30-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ae8c62fe2480dd61c532ccafdbce9b29dacc126fe8be0d9a927ca3e699b9491a"}, + {file = "SQLAlchemy-2.0.30-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2383146973a15435e4717f94c7509982770e3e54974c71f76500a0136f22810b"}, + {file = "SQLAlchemy-2.0.30-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8409de825f2c3b62ab15788635ccaec0c881c3f12a8af2b12ae4910a0a9aeef6"}, + {file = "SQLAlchemy-2.0.30-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0094c5dc698a5f78d3d1539853e8ecec02516b62b8223c970c86d44e7a80f6c7"}, + {file = "SQLAlchemy-2.0.30-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:edc16a50f5e1b7a06a2dcc1f2205b0b961074c123ed17ebda726f376a5ab0953"}, + {file = "SQLAlchemy-2.0.30-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f7703c2010355dd28f53deb644a05fc30f796bd8598b43f0ba678878780b6e4c"}, + {file = "SQLAlchemy-2.0.30-cp39-cp39-win32.whl", hash = "sha256:1f9a727312ff6ad5248a4367358e2cf7e625e98b1028b1d7ab7b806b7d757513"}, + {file = "SQLAlchemy-2.0.30-cp39-cp39-win_amd64.whl", hash = "sha256:a0ef36b28534f2a5771191be6edb44cc2673c7b2edf6deac6562400288664221"}, + {file = "SQLAlchemy-2.0.30-py3-none-any.whl", hash = "sha256:7108d569d3990c71e26a42f60474b4c02c8586c4681af5fd67e51a044fdea86a"}, + {file = "SQLAlchemy-2.0.30.tar.gz", hash = "sha256:2b1708916730f4830bc69d6f49d37f7698b5bd7530aca7f04f785f8849e95255"}, +] + +[package.dependencies] +greenlet = {version = "!=0.4.17", markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\""} +typing-extensions = ">=4.6.0" + +[package.extras] +aiomysql = ["aiomysql (>=0.2.0)", "greenlet (!=0.4.17)"] +aioodbc = ["aioodbc", "greenlet (!=0.4.17)"] +aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing_extensions (!=3.10.0.1)"] +asyncio = ["greenlet (!=0.4.17)"] +asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (!=0.4.17)"] +mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5)"] +mssql = ["pyodbc"] +mssql-pymssql = ["pymssql"] +mssql-pyodbc = ["pyodbc"] +mypy = ["mypy (>=0.910)"] +mysql = ["mysqlclient (>=1.4.0)"] +mysql-connector = ["mysql-connector-python"] +oracle = ["cx_oracle (>=8)"] +oracle-oracledb = ["oracledb (>=1.0.1)"] +postgresql = ["psycopg2 (>=2.7)"] +postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"] +postgresql-pg8000 = ["pg8000 (>=1.29.1)"] +postgresql-psycopg = ["psycopg (>=3.0.7)"] +postgresql-psycopg2binary = ["psycopg2-binary"] +postgresql-psycopg2cffi = ["psycopg2cffi"] +postgresql-psycopgbinary = ["psycopg[binary] (>=3.0.7)"] +pymysql = ["pymysql"] +sqlcipher = ["sqlcipher3_binary"] + [[package]] name = "stack-data" version = "0.6.3" @@ -3276,6 +4949,17 @@ files = [ [package.extras] widechars = ["wcwidth"] +[[package]] +name = "tblib" +version = "3.0.0" +description = "Traceback serialization library." +optional = false +python-versions = ">=3.8" +files = [ + {file = "tblib-3.0.0-py3-none-any.whl", hash = "sha256:80a6c77e59b55e83911e1e607c649836a69c103963c5f28a46cbeef44acf8129"}, + {file = "tblib-3.0.0.tar.gz", hash = "sha256:93622790a0a29e04f0346458face1e144dc4d32f493714c6c3dff82a4adb77e6"}, +] + [[package]] name = "temporalio" version = "1.6.0" @@ -3301,6 +4985,21 @@ typing-extensions = ">=4.2.0,<5.0.0" grpc = ["grpcio (>=1.59.0,<2.0.0)"] opentelemetry = ["opentelemetry-api (>=1.11.1,<2.0.0)", "opentelemetry-sdk (>=1.11.1,<2.0.0)"] +[[package]] +name = "tenacity" +version = "8.3.0" +description = "Retry code until it succeeds" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tenacity-8.3.0-py3-none-any.whl", hash = "sha256:3649f6443dbc0d9b01b9d8020a9c4ec7a1ff5f6f3c6c8a036ef371f573fe9185"}, + {file = "tenacity-8.3.0.tar.gz", hash = "sha256:953d4e6ad24357bceffbc9707bc74349aca9d245f68eb65419cf0c249a1949a2"}, +] + +[package.extras] +doc = ["reno", "sphinx"] +test = ["pytest", "tornado (>=4.5)", "typeguard"] + [[package]] name = "termcolor" version = "2.4.0" @@ -3315,6 +5014,27 @@ files = [ [package.extras] tests = ["pytest", "pytest-cov"] +[[package]] +name = "terminado" +version = "0.18.1" +description = "Tornado websocket backend for the Xterm.js Javascript terminal emulator library." +optional = false +python-versions = ">=3.8" +files = [ + {file = "terminado-0.18.1-py3-none-any.whl", hash = "sha256:a4468e1b37bb318f8a86514f65814e1afc977cf29b3992a4500d9dd305dcceb0"}, + {file = "terminado-0.18.1.tar.gz", hash = "sha256:de09f2c4b85de4765f7714688fff57d3e75bad1f909b589fde880460c753fd2e"}, +] + +[package.dependencies] +ptyprocess = {version = "*", markers = "os_name != \"nt\""} +pywinpty = {version = ">=1.1.0", markers = "os_name == \"nt\""} +tornado = ">=6.1.0" + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] +test = ["pre-commit", "pytest (>=7.0)", "pytest-timeout"] +typing = ["mypy (>=1.6,<2.0)", "traitlets (>=5.11.1)"] + [[package]] name = "tiktoken" version = "0.6.0" @@ -3367,6 +5087,24 @@ requests = ">=2.26.0" [package.extras] blobfile = ["blobfile (>=2)"] +[[package]] +name = "tinycss2" +version = "1.3.0" +description = "A tiny CSS parser" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tinycss2-1.3.0-py3-none-any.whl", hash = "sha256:54a8dbdffb334d536851be0226030e9505965bb2f30f21a4a82c55fb2a80fae7"}, + {file = "tinycss2-1.3.0.tar.gz", hash = "sha256:152f9acabd296a8375fbca5b84c961ff95971fcfc32e79550c8df8e29118c54d"}, +] + +[package.dependencies] +webencodings = ">=0.4" + +[package.extras] +doc = ["sphinx", "sphinx_rtd_theme"] +test = ["pytest", "ruff"] + [[package]] name = "tokenizers" version = "0.19.1" @@ -3506,6 +5244,37 @@ files = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] +[[package]] +name = "toolz" +version = "0.12.1" +description = "List processing tools and functional utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "toolz-0.12.1-py3-none-any.whl", hash = "sha256:d22731364c07d72eea0a0ad45bafb2c2937ab6fd38a3507bf55eae8744aa7d85"}, + {file = "toolz-0.12.1.tar.gz", hash = "sha256:ecca342664893f177a13dac0e6b41cbd8ac25a358e5f215316d43e2100224f4d"}, +] + +[[package]] +name = "tornado" +version = "6.4" +description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." +optional = false +python-versions = ">= 3.8" +files = [ + {file = "tornado-6.4-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:02ccefc7d8211e5a7f9e8bc3f9e5b0ad6262ba2fbb683a6443ecc804e5224ce0"}, + {file = "tornado-6.4-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:27787de946a9cffd63ce5814c33f734c627a87072ec7eed71f7fc4417bb16263"}, + {file = "tornado-6.4-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7894c581ecdcf91666a0912f18ce5e757213999e183ebfc2c3fdbf4d5bd764e"}, + {file = "tornado-6.4-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e43bc2e5370a6a8e413e1e1cd0c91bedc5bd62a74a532371042a18ef19e10579"}, + {file = "tornado-6.4-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0251554cdd50b4b44362f73ad5ba7126fc5b2c2895cc62b14a1c2d7ea32f212"}, + {file = "tornado-6.4-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fd03192e287fbd0899dd8f81c6fb9cbbc69194d2074b38f384cb6fa72b80e9c2"}, + {file = "tornado-6.4-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:88b84956273fbd73420e6d4b8d5ccbe913c65d31351b4c004ae362eba06e1f78"}, + {file = "tornado-6.4-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:71ddfc23a0e03ef2df1c1397d859868d158c8276a0603b96cf86892bff58149f"}, + {file = "tornado-6.4-cp38-abi3-win32.whl", hash = "sha256:6f8a6c77900f5ae93d8b4ae1196472d0ccc2775cc1dfdc9e7727889145c45052"}, + {file = "tornado-6.4-cp38-abi3-win_amd64.whl", hash = "sha256:10aeaa8006333433da48dec9fe417877f8bcc21f48dda8d661ae79da357b2a63"}, + {file = "tornado-6.4.tar.gz", hash = "sha256:72291fa6e6bc84e626589f1c29d90a5a6d593ef5ae68052ee2ef000dfd273dee"}, +] + [[package]] name = "tqdm" version = "4.66.4" @@ -3657,6 +5426,21 @@ files = [ {file = "typing_extensions-4.12.1.tar.gz", hash = "sha256:915f5e35ff76f56588223f15fdd5938f9a1cf9195c0de25130c627e4d597f6d1"}, ] +[[package]] +name = "typing-inspect" +version = "0.9.0" +description = "Runtime inspection utilities for typing module." +optional = false +python-versions = "*" +files = [ + {file = "typing_inspect-0.9.0-py3-none-any.whl", hash = "sha256:9ee6fc59062311ef8547596ab6b955e1b8aa46242d854bfc78f4f6b0eff35f9f"}, + {file = "typing_inspect-0.9.0.tar.gz", hash = "sha256:b23fc42ff6f6ef6954e4852c1fb512cdd18dbea03134f91f856a95ccc9461f78"}, +] + +[package.dependencies] +mypy-extensions = ">=0.3.0" +typing-extensions = ">=3.7.4" + [[package]] name = "tzdata" version = "2024.1" @@ -3668,6 +5452,20 @@ files = [ {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, ] +[[package]] +name = "uri-template" +version = "1.3.0" +description = "RFC 6570 URI Template Processor" +optional = false +python-versions = ">=3.7" +files = [ + {file = "uri-template-1.3.0.tar.gz", hash = "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7"}, + {file = "uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363"}, +] + +[package.extras] +dev = ["flake8", "flake8-annotations", "flake8-bandit", "flake8-bugbear", "flake8-commas", "flake8-comprehensions", "flake8-continuation", "flake8-datetimez", "flake8-docstrings", "flake8-import-order", "flake8-literal", "flake8-modern-annotations", "flake8-noqa", "flake8-pyproject", "flake8-requirements", "flake8-typechecking-import", "flake8-use-fstring", "mypy", "pep8-naming", "types-PyYAML"] + [[package]] name = "urllib3" version = "2.2.1" @@ -3736,6 +5534,59 @@ files = [ {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, ] +[[package]] +name = "webcolors" +version = "1.13" +description = "A library for working with the color formats defined by HTML and CSS." +optional = false +python-versions = ">=3.7" +files = [ + {file = "webcolors-1.13-py3-none-any.whl", hash = "sha256:29bc7e8752c0a1bd4a1f03c14d6e6a72e93d82193738fa860cbff59d0fcc11bf"}, + {file = "webcolors-1.13.tar.gz", hash = "sha256:c225b674c83fa923be93d235330ce0300373d02885cef23238813b0d5668304a"}, +] + +[package.extras] +docs = ["furo", "sphinx", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-notfound-page", "sphinxext-opengraph"] +tests = ["pytest", "pytest-cov"] + +[[package]] +name = "webencodings" +version = "0.5.1" +description = "Character encoding aliases for legacy web content" +optional = false +python-versions = "*" +files = [ + {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, + {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, +] + +[[package]] +name = "websocket-client" +version = "1.8.0" +description = "WebSocket client for Python with low level API options" +optional = false +python-versions = ">=3.8" +files = [ + {file = "websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526"}, + {file = "websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da"}, +] + +[package.extras] +docs = ["Sphinx (>=6.0)", "myst-parser (>=2.0.0)", "sphinx-rtd-theme (>=1.1.0)"] +optional = ["python-socks", "wsaccel"] +test = ["websockets"] + +[[package]] +name = "widgetsnbextension" +version = "4.0.11" +description = "Jupyter interactive widgets for Jupyter Notebook" +optional = false +python-versions = ">=3.7" +files = [ + {file = "widgetsnbextension-4.0.11-py3-none-any.whl", hash = "sha256:55d4d6949d100e0d08b94948a42efc3ed6dfdc0e9468b2c4b128c9a2ce3a7a36"}, + {file = "widgetsnbextension-4.0.11.tar.gz", hash = "sha256:8b22a8f1910bfd188e596fe7fc05dcbd87e810c8a4ba010bdb3da86637398474"}, +] + [[package]] name = "xxhash" version = "3.4.1" @@ -3956,22 +5807,33 @@ files = [ idna = ">=2.0" multidict = ">=4.0" +[[package]] +name = "zict" +version = "3.0.0" +description = "Mutable mapping tools" +optional = false +python-versions = ">=3.8" +files = [ + {file = "zict-3.0.0-py2.py3-none-any.whl", hash = "sha256:5796e36bd0e0cc8cf0fbc1ace6a68912611c1dbd74750a3f3026b9b9d6a327ae"}, + {file = "zict-3.0.0.tar.gz", hash = "sha256:e321e263b6a97aafc0790c3cfb3c04656b7066e6738c37fffcca95d803c9fba5"}, +] + [[package]] name = "zipp" -version = "3.19.2" +version = "3.19.1" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.8" files = [ - {file = "zipp-3.19.2-py3-none-any.whl", hash = "sha256:f091755f667055f2d02b32c53771a7a6c8b47e1fdbc4b72a8b9072b3eef8015c"}, - {file = "zipp-3.19.2.tar.gz", hash = "sha256:bf1dcf6450f873a13e952a29504887c89e6de7506209e5b1bcc3460135d4de19"}, + {file = "zipp-3.19.1-py3-none-any.whl", hash = "sha256:2828e64edb5386ea6a52e7ba7cdb17bb30a73a858f5eb6eb93d8d36f5ea26091"}, + {file = "zipp-3.19.1.tar.gz", hash = "sha256:35427f6d5594f4acf82d25541438348c26736fa9b3afa2754bcd63cdb99d8e8f"}, ] [package.extras] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] +test = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.11" -content-hash = "3342e4723ae2e448074da082ab6d9db5dea78ede813d1ad8241f39ee97e96b12" +content-hash = "32799f56a3e625e2ae5291f88e4225d30bc878c29e5cf4d40d04c346b75381e9" \ No newline at end of file diff --git a/agents-api/pyproject.toml b/agents-api/pyproject.toml index 82545c3c4..51c62df55 100644 --- a/agents-api/pyproject.toml +++ b/agents-api/pyproject.toml @@ -30,6 +30,7 @@ numpy = "^1.26.4" transformers = "^4.40.1" tiktoken = "^0.6.0" xxhash = "^3.4.1" +tenacity = "^8.3.0" beartype = "^0.18.5" @@ -44,6 +45,10 @@ pytype = ">=2024.4.11" julep = "^0.2.4" pyjwt = "^2.8.0" ward = "^0.68.0b0" +jupyterlab = "^4.1.8" +ipywidgets = "^8.1.2" +jupyter-ai = "^2.14.1" +langchain-openai = "^0.1.6" [build-system] requires = ["poetry-core"] diff --git a/agents-api/tests/__init__.py b/agents-api/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/agents-api/tests/test_activities.py b/agents-api/tests/test_activities.py new file mode 100644 index 000000000..70581c378 --- /dev/null +++ b/agents-api/tests/test_activities.py @@ -0,0 +1,90 @@ +import time +import uuid +from ward import test +from agents_api.common.protocol.entries import Entry +from agents_api.autogen.openapi_model import Role +from agents_api.activities.truncation import get_extra_entries + + +@test("get extra entries, do not strip system message") +def _(): + session_ids = [uuid.uuid4()] * 3 + entry_ids = [uuid.uuid4()] * 3 + now = time.time() + messages = [ + Entry( + entry_id=entry_ids[0], + session_id=session_ids[0], + role=Role.system, + content="content 1", + created_at=now, + timestamp=now, + ), + Entry( + entry_id=entry_ids[1], + session_id=session_ids[1], + role=Role.assistant, + content="content 2", + created_at=now, + timestamp=now, + ), + Entry( + entry_id=entry_ids[2], + session_id=session_ids[2], + role=Role.user, + content="content 3", + created_at=now, + timestamp=now, + ), + ] + + threshold = sum([m.token_count for m in messages]) - 1 + result = get_extra_entries(messages, threshold) + + assert result == [messages[1].id] + + +@test("get extra entries") +def _(): + session_ids = [uuid.uuid4()] * 3 + entry_ids = [uuid.uuid4()] * 3 + now = time.time() + messages = [ + Entry( + entry_id=entry_ids[0], + session_id=session_ids[0], + role=Role.user, + content="content 1", + created_at=now, + timestamp=now, + ), + Entry( + entry_id=entry_ids[1], + session_id=session_ids[1], + role=Role.assistant, + content="content 2", + created_at=now, + timestamp=now, + ), + Entry( + entry_id=entry_ids[2], + session_id=session_ids[2], + role=Role.user, + content="content 3", + created_at=now, + timestamp=now, + ), + ] + + threshold = sum([m.token_count for m in messages]) - 1 + result = get_extra_entries(messages, threshold) + + assert result == [messages[0].id] + + +@test("get extra entries, no change if empty") +def _(): + messages = [] + result = get_extra_entries(messages, 1) + + assert result == [] diff --git a/mock_openapi.yaml b/mock_openapi.yaml index 763e4fbf8..a83e167d0 100644 --- a/mock_openapi.yaml +++ b/mock_openapi.yaml @@ -1298,6 +1298,12 @@ components: type: boolean description: Render system and assistant message content as jinja templates default: false + token_budget: + type: integer + description: Threshold value for the adaptive context functionality + context_overflow: + type: string + description: Action to start on context window overflow required: - id - agent_id @@ -1346,6 +1352,12 @@ components: type: boolean description: Render system and assistant message content as jinja templates default: false + token_budget: + type: integer + description: Threshold value for the adaptive context functionality + context_overflow: + type: string + description: Action to start on context window overflow required: - agent_id description: A valid request payload for creating a session @@ -1407,6 +1419,12 @@ components: type: object properties: {} description: Optional metadata + token_budget: + type: integer + description: Threshold value for the adaptive context functionality + context_overflow: + type: string + description: Action to start on context window overflow description: A valid request payload for updating a session required: - situation @@ -2322,6 +2340,12 @@ components: type: object properties: {} description: Optional metadata + token_budget: + type: integer + description: Threshold value for the adaptive context functionality + context_overflow: + type: string + description: Action to start on context window overflow description: A request for patching a session PatchToolRequest: type: object diff --git a/openapi.yaml b/openapi.yaml index f675b82dc..72f532fd9 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1298,6 +1298,12 @@ components: type: boolean description: Render system and assistant message content as jinja templates default: false + token_budget: + type: integer + description: Threshold value for the adaptive context functionality + context_overflow: + type: string + description: Action to start on context window overflow required: - id - agent_id @@ -1346,6 +1352,12 @@ components: type: boolean description: Render system and assistant message content as jinja templates default: false + token_budget: + type: integer + description: Threshold value for the adaptive context functionality + context_overflow: + type: string + description: Action to start on context window overflow required: - agent_id description: A valid request payload for creating a session @@ -1407,6 +1419,12 @@ components: type: object properties: {} description: Optional metadata + token_budget: + type: integer + description: Threshold value for the adaptive context functionality + context_overflow: + type: string + description: Action to start on context window overflow description: A valid request payload for updating a session required: - situation @@ -2322,6 +2340,12 @@ components: type: object properties: {} description: Optional metadata + token_budget: + type: integer + description: Threshold value for the adaptive context functionality + context_overflow: + type: string + description: Action to start on context window overflow description: A request for patching a session PatchToolRequest: type: object diff --git a/sdks/postman/collection.json b/sdks/postman/collection.json index 16eed0839..07e71271e 100644 --- a/sdks/postman/collection.json +++ b/sdks/postman/collection.json @@ -106,7 +106,7 @@ "body": null }, "description": "List of sessions (sorted created_at descending order) with limit+offset pagination", - "body": "{\n \"items\": [\n {\n \"id\": \"id\",\n \"user_id\": \"user_id\",\n \"agent_id\": \"agent_id\",\n \"situation\": \"situation\",\n \"summary\": \"summary\",\n \"created_at\": \"2024-01-15T09:30:00Z\",\n \"updated_at\": \"2024-01-15T09:30:00Z\",\n \"render_templates\": true\n }\n ]\n}", + "body": "{\n \"items\": [\n {\n \"id\": \"id\",\n \"user_id\": \"user_id\",\n \"agent_id\": \"agent_id\",\n \"situation\": \"situation\",\n \"summary\": \"summary\",\n \"created_at\": \"2024-01-15T09:30:00Z\",\n \"updated_at\": \"2024-01-15T09:30:00Z\",\n \"render_templates\": true,\n \"token_budget\": 1,\n \"context_overflow\": \"context_overflow\"\n }\n ]\n}", "_postman_previewlanguage": "json" } ] @@ -612,7 +612,7 @@ "body": null }, "description": null, - "body": "{\n \"id\": \"id\",\n \"user_id\": \"user_id\",\n \"agent_id\": \"agent_id\",\n \"situation\": \"situation\",\n \"summary\": \"summary\",\n \"created_at\": \"2024-01-15T09:30:00Z\",\n \"updated_at\": \"2024-01-15T09:30:00Z\",\n \"render_templates\": true\n}", + "body": "{\n \"id\": \"id\",\n \"user_id\": \"user_id\",\n \"agent_id\": \"agent_id\",\n \"situation\": \"situation\",\n \"summary\": \"summary\",\n \"created_at\": \"2024-01-15T09:30:00Z\",\n \"updated_at\": \"2024-01-15T09:30:00Z\",\n \"render_templates\": true,\n \"token_budget\": 1,\n \"context_overflow\": \"context_overflow\"\n}", "_postman_previewlanguage": "json" } ] diff --git a/sdks/python/julep/api/client.py b/sdks/python/julep/api/client.py index 0ac307a05..afc148aaf 100644 --- a/sdks/python/julep/api/client.py +++ b/sdks/python/julep/api/client.py @@ -149,6 +149,8 @@ def create_session( situation: typing.Optional[str] = OMIT, metadata: typing.Optional[CreateSessionRequestMetadata] = OMIT, render_templates: typing.Optional[bool] = OMIT, + token_budget: typing.Optional[int] = OMIT, + context_overflow: typing.Optional[str] = OMIT, ) -> ResourceCreatedResponse: """ Create a session between an agent and a user @@ -163,6 +165,10 @@ def create_session( - metadata: typing.Optional[CreateSessionRequestMetadata]. Optional metadata - render_templates: typing.Optional[bool]. Render system and assistant message content as jinja templates + + - token_budget: typing.Optional[int]. Threshold value for the adaptive context functionality + + - context_overflow: typing.Optional[str]. Action to start on context window overflow --- from julep.client import JulepApi @@ -182,6 +188,10 @@ def create_session( _request["metadata"] = metadata if render_templates is not OMIT: _request["render_templates"] = render_templates + if token_budget is not OMIT: + _request["token_budget"] = token_budget + if context_overflow is not OMIT: + _request["context_overflow"] = context_overflow _response = self._client_wrapper.httpx_client.request( "POST", urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "sessions"), @@ -463,6 +473,8 @@ def update_session( *, situation: str, metadata: typing.Optional[UpdateSessionRequestMetadata] = OMIT, + token_budget: typing.Optional[int] = OMIT, + context_overflow: typing.Optional[str] = OMIT, ) -> ResourceUpdatedResponse: """ @@ -473,6 +485,10 @@ def update_session( - situation: str. Updated situation for this session - metadata: typing.Optional[UpdateSessionRequestMetadata]. Optional metadata + + - token_budget: typing.Optional[int]. Threshold value for the adaptive context functionality + + - context_overflow: typing.Optional[str]. Action to start on context window overflow --- from julep.client import JulepApi @@ -487,6 +503,10 @@ def update_session( _request: typing.Dict[str, typing.Any] = {"situation": situation} if metadata is not OMIT: _request["metadata"] = metadata + if token_budget is not OMIT: + _request["token_budget"] = token_budget + if context_overflow is not OMIT: + _request["context_overflow"] = context_overflow _response = self._client_wrapper.httpx_client.request( "PUT", urllib.parse.urljoin( @@ -542,6 +562,8 @@ def patch_session( *, situation: typing.Optional[str] = OMIT, metadata: typing.Optional[PatchSessionRequestMetadata] = OMIT, + token_budget: typing.Optional[int] = OMIT, + context_overflow: typing.Optional[str] = OMIT, ) -> ResourceUpdatedResponse: """ @@ -552,6 +574,10 @@ def patch_session( - situation: typing.Optional[str]. Updated situation for this session - metadata: typing.Optional[PatchSessionRequestMetadata]. Optional metadata + + - token_budget: typing.Optional[int]. Threshold value for the adaptive context functionality + + - context_overflow: typing.Optional[str]. Action to start on context window overflow --- from julep.client import JulepApi @@ -567,6 +593,10 @@ def patch_session( _request["situation"] = situation if metadata is not OMIT: _request["metadata"] = metadata + if token_budget is not OMIT: + _request["token_budget"] = token_budget + if context_overflow is not OMIT: + _request["context_overflow"] = context_overflow _response = self._client_wrapper.httpx_client.request( "PATCH", urllib.parse.urljoin( @@ -1910,6 +1940,8 @@ async def create_session( situation: typing.Optional[str] = OMIT, metadata: typing.Optional[CreateSessionRequestMetadata] = OMIT, render_templates: typing.Optional[bool] = OMIT, + token_budget: typing.Optional[int] = OMIT, + context_overflow: typing.Optional[str] = OMIT, ) -> ResourceCreatedResponse: """ Create a session between an agent and a user @@ -1924,6 +1956,10 @@ async def create_session( - metadata: typing.Optional[CreateSessionRequestMetadata]. Optional metadata - render_templates: typing.Optional[bool]. Render system and assistant message content as jinja templates + + - token_budget: typing.Optional[int]. Threshold value for the adaptive context functionality + + - context_overflow: typing.Optional[str]. Action to start on context window overflow --- from julep.client import AsyncJulepApi @@ -1943,6 +1979,10 @@ async def create_session( _request["metadata"] = metadata if render_templates is not OMIT: _request["render_templates"] = render_templates + if token_budget is not OMIT: + _request["token_budget"] = token_budget + if context_overflow is not OMIT: + _request["context_overflow"] = context_overflow _response = await self._client_wrapper.httpx_client.request( "POST", urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "sessions"), @@ -2224,6 +2264,8 @@ async def update_session( *, situation: str, metadata: typing.Optional[UpdateSessionRequestMetadata] = OMIT, + token_budget: typing.Optional[int] = OMIT, + context_overflow: typing.Optional[str] = OMIT, ) -> ResourceUpdatedResponse: """ @@ -2234,6 +2276,10 @@ async def update_session( - situation: str. Updated situation for this session - metadata: typing.Optional[UpdateSessionRequestMetadata]. Optional metadata + + - token_budget: typing.Optional[int]. Threshold value for the adaptive context functionality + + - context_overflow: typing.Optional[str]. Action to start on context window overflow --- from julep.client import AsyncJulepApi @@ -2248,6 +2294,10 @@ async def update_session( _request: typing.Dict[str, typing.Any] = {"situation": situation} if metadata is not OMIT: _request["metadata"] = metadata + if token_budget is not OMIT: + _request["token_budget"] = token_budget + if context_overflow is not OMIT: + _request["context_overflow"] = context_overflow _response = await self._client_wrapper.httpx_client.request( "PUT", urllib.parse.urljoin( @@ -2303,6 +2353,8 @@ async def patch_session( *, situation: typing.Optional[str] = OMIT, metadata: typing.Optional[PatchSessionRequestMetadata] = OMIT, + token_budget: typing.Optional[int] = OMIT, + context_overflow: typing.Optional[str] = OMIT, ) -> ResourceUpdatedResponse: """ @@ -2313,6 +2365,10 @@ async def patch_session( - situation: typing.Optional[str]. Updated situation for this session - metadata: typing.Optional[PatchSessionRequestMetadata]. Optional metadata + + - token_budget: typing.Optional[int]. Threshold value for the adaptive context functionality + + - context_overflow: typing.Optional[str]. Action to start on context window overflow --- from julep.client import AsyncJulepApi @@ -2328,6 +2384,10 @@ async def patch_session( _request["situation"] = situation if metadata is not OMIT: _request["metadata"] = metadata + if token_budget is not OMIT: + _request["token_budget"] = token_budget + if context_overflow is not OMIT: + _request["context_overflow"] = context_overflow _response = await self._client_wrapper.httpx_client.request( "PATCH", urllib.parse.urljoin( diff --git a/sdks/python/julep/api/types/session.py b/sdks/python/julep/api/types/session.py index 97c442cd5..e5b6aafe2 100644 --- a/sdks/python/julep/api/types/session.py +++ b/sdks/python/julep/api/types/session.py @@ -38,6 +38,12 @@ class Session(pydantic.BaseModel): render_templates: typing.Optional[bool] = pydantic.Field( description="Render system and assistant message content as jinja templates" ) + token_budget: typing.Optional[int] = pydantic.Field( + description="Threshold value for the adaptive context functionality" + ) + context_overflow: typing.Optional[str] = pydantic.Field( + description="Action to start on context window overflow" + ) def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = { diff --git a/sdks/python/julep/managers/session.py b/sdks/python/julep/managers/session.py index a61436b6b..a083c4f29 100644 --- a/sdks/python/julep/managers/session.py +++ b/sdks/python/julep/managers/session.py @@ -40,6 +40,8 @@ class SessionCreateArgs(TypedDict): situation: Optional[str] = None metadata: Dict[str, Any] = {} render_templates: bool = False + token_budget: Optional[int] = None + context_overflow: Optional[str] = None class SessionUpdateArgs(TypedDict): @@ -48,6 +50,8 @@ class SessionUpdateArgs(TypedDict): metadata: Optional[Dict[str, Any]] = None overwrite: bool = False render_templates: bool = False + token_budget: Optional[int] = None + context_overflow: Optional[str] = None class BaseSessionsManager(BaseManager): @@ -182,6 +186,8 @@ def _create( situation: Optional[str] = None, metadata: Dict[str, Any] = {}, render_templates: bool = False, + token_budget: Optional[int] = None, + context_overflow: Optional[str] = None, ) -> Union[ResourceCreatedResponse, Awaitable[ResourceCreatedResponse]]: # Cast instructions to a list of Instruction objects """ @@ -213,6 +219,8 @@ def _create( situation=situation, metadata=metadata, render_templates=render_templates, + token_budget=token_budget, + context_overflow=context_overflow, ) def _list_items( @@ -267,6 +275,8 @@ def _update( situation: Optional[str] = None, metadata: Optional[Dict[str, Any]] = None, overwrite: bool = False, + token_budget: Optional[int] = None, + context_overflow: Optional[str] = None, ) -> Union[ResourceUpdatedResponse, Awaitable[ResourceUpdatedResponse]]: """ Update a session with a given situation. @@ -293,6 +303,8 @@ def _update( session_id=session_id, situation=situation, metadata=metadata, + token_budget=token_budget, + context_overflow=context_overflow, ) def _chat( diff --git a/sdks/ts/src/api/models/CreateSessionRequest.ts b/sdks/ts/src/api/models/CreateSessionRequest.ts index bdb4e699f..47cc2bf0f 100644 --- a/sdks/ts/src/api/models/CreateSessionRequest.ts +++ b/sdks/ts/src/api/models/CreateSessionRequest.ts @@ -26,4 +26,12 @@ export type CreateSessionRequest = { * Render system and assistant message content as jinja templates */ render_templates?: boolean; + /** + * Threshold value for the adaptive context functionality + */ + token_budget?: number; + /** + * Action to start on context window overflow + */ + context_overflow?: string; }; diff --git a/sdks/ts/src/api/models/PatchSessionRequest.ts b/sdks/ts/src/api/models/PatchSessionRequest.ts index 5d1d43650..4a109cfee 100644 --- a/sdks/ts/src/api/models/PatchSessionRequest.ts +++ b/sdks/ts/src/api/models/PatchSessionRequest.ts @@ -14,4 +14,12 @@ export type PatchSessionRequest = { * Optional metadata */ metadata?: any; + /** + * Threshold value for the adaptive context functionality + */ + token_budget?: number; + /** + * Action to start on context window overflow + */ + context_overflow?: string; }; diff --git a/sdks/ts/src/api/models/Session.ts b/sdks/ts/src/api/models/Session.ts index 2312a7a4b..27ed7f7f1 100644 --- a/sdks/ts/src/api/models/Session.ts +++ b/sdks/ts/src/api/models/Session.ts @@ -39,4 +39,12 @@ export type Session = { * Render system and assistant message content as jinja templates */ render_templates?: boolean; + /** + * Threshold value for the adaptive context functionality + */ + token_budget?: number; + /** + * Action to start on context window overflow + */ + context_overflow?: string; }; diff --git a/sdks/ts/src/api/models/UpdateSessionRequest.ts b/sdks/ts/src/api/models/UpdateSessionRequest.ts index b26b2e944..50e3bd14f 100644 --- a/sdks/ts/src/api/models/UpdateSessionRequest.ts +++ b/sdks/ts/src/api/models/UpdateSessionRequest.ts @@ -14,4 +14,12 @@ export type UpdateSessionRequest = { * Optional metadata */ metadata?: any; + /** + * Threshold value for the adaptive context functionality + */ + token_budget?: number; + /** + * Action to start on context window overflow + */ + context_overflow?: string; }; diff --git a/sdks/ts/src/api/schemas/$CreateSessionRequest.ts b/sdks/ts/src/api/schemas/$CreateSessionRequest.ts index 647a066b3..79d56647e 100644 --- a/sdks/ts/src/api/schemas/$CreateSessionRequest.ts +++ b/sdks/ts/src/api/schemas/$CreateSessionRequest.ts @@ -28,5 +28,13 @@ export const $CreateSessionRequest = { type: "boolean", description: `Render system and assistant message content as jinja templates`, }, + token_budget: { + type: "number", + description: `Threshold value for the adaptive context functionality`, + }, + context_overflow: { + type: "string", + description: `Action to start on context window overflow`, + }, }, } as const; diff --git a/sdks/ts/src/api/schemas/$PatchSessionRequest.ts b/sdks/ts/src/api/schemas/$PatchSessionRequest.ts index fb64543d6..f6c0b4d75 100644 --- a/sdks/ts/src/api/schemas/$PatchSessionRequest.ts +++ b/sdks/ts/src/api/schemas/$PatchSessionRequest.ts @@ -13,5 +13,13 @@ export const $PatchSessionRequest = { description: `Optional metadata`, properties: {}, }, + token_budget: { + type: "number", + description: `Threshold value for the adaptive context functionality`, + }, + context_overflow: { + type: "string", + description: `Action to start on context window overflow`, + }, }, } as const; diff --git a/sdks/ts/src/api/schemas/$Session.ts b/sdks/ts/src/api/schemas/$Session.ts index ccbbff296..24354f4f4 100644 --- a/sdks/ts/src/api/schemas/$Session.ts +++ b/sdks/ts/src/api/schemas/$Session.ts @@ -47,5 +47,13 @@ export const $Session = { type: "boolean", description: `Render system and assistant message content as jinja templates`, }, + token_budget: { + type: "number", + description: `Threshold value for the adaptive context functionality`, + }, + context_overflow: { + type: "string", + description: `Action to start on context window overflow`, + }, }, } as const; diff --git a/sdks/ts/src/api/schemas/$UpdateSessionRequest.ts b/sdks/ts/src/api/schemas/$UpdateSessionRequest.ts index 95180ec84..9b415c138 100644 --- a/sdks/ts/src/api/schemas/$UpdateSessionRequest.ts +++ b/sdks/ts/src/api/schemas/$UpdateSessionRequest.ts @@ -14,5 +14,13 @@ export const $UpdateSessionRequest = { description: `Optional metadata`, properties: {}, }, + token_budget: { + type: "number", + description: `Threshold value for the adaptive context functionality`, + }, + context_overflow: { + type: "string", + description: `Action to start on context window overflow`, + }, }, } as const;