diff --git a/.gitignore b/.gitignore index 44c48644..48cee815 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,9 @@ wheels/ # NLTK data (will be downloaded automatically) nltk_data/ + +# Large benchmark datasets (will be downloaded automatically) +benchmarks/longmemeval/longmemeval_s_cleaned.json + +# Debug logs +logs/ diff --git a/CLAUDE.md b/CLAUDE.md index 2651728e..a1612c1f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,6 +2,7 @@ Do not write any markdown file, just write the code. # Workflow -After your changes, make sure everything is working fine by running the main script. +- After your changes, make sure everything is working fine by running the tests. - keep the readme.md architecture section up to date when you change the implementation -- when changing an implemetation, do not keep the old one as fallback \ No newline at end of file +- when changing an implemetation, do not keep the old one as fallback +- to run test, use uv run pytest tests \ No newline at end of file diff --git a/README.md b/README.md index 607a014c..f4e3a84d 100644 --- a/README.md +++ b/README.md @@ -90,43 +90,44 @@ The combination of these three networks enables powerful memory retrieval that g The search algorithm explores the memory graph using spreading activation: -1. **Entry Points**: Find top-3 semantically similar memories to the query (vector search) -2. **Activation Spreading**: Start with activation = 1.0 at entry points +1. **Entry Points**: Find top-3 semantically similar memories to the query (vector search, similarity ≥ 0.5) +2. **Activation Spreading**: Start with activation = actual similarity score (0.5 to 1.0) at entry points 3. **Graph Traversal**: Follow links to neighbors, spreading activation with decay (0.8 factor) 4. **Thinking Budget**: Limit exploration to N units (controls computational cost) -5. **Dynamic Weighting**: Combine activation with recency and frequency: +5. **Dynamic Weighting**: Combine activation, semantic similarity, recency, and frequency: ``` - final_weight = activation × recency × frequency + final_weight = 0.30 × activation + 0.30 × semantic_similarity + 0.25 × recency + 0.15 × frequency + semantic_similarity = cosine_similarity(query_embedding, memory_embedding) recency = exp(-0.1 × days_since) - frequency = 1.0 + log(access_count + 1) / log(10) + frequency = normalized to [0, 1] from log(access_count + 1) / log(10) ``` 6. **Return Top-K**: Sort by final weight and return top results This approach ensures: -- Recently accessed memories get boosted (recency bias) -- Frequently accessed memories get boosted (importance signal) -- Graph structure influences results (not just vector similarity) +- Semantic relevance to query is always considered (30% weight) +- Graph structure influences results through activation (30% weight) +- Recently accessed memories get boosted (25% weight - recency bias) +- Frequently accessed memories get boosted (15% weight - importance signal) ### Self-Contained Memory Units -Every memory unit is processed to be self-contained through coreference resolution: +Every memory unit is self-contained through LLM fact extraction: **Problem**: "She joined Google last year" - unclear who "she" is -**Solution**: Fast batch coreference resolution that: -- Replaces personal pronouns (he, she, it, they) with actual referents -- Processes all sentences in one batch (O(n) instead of O(n²)) -- Uses neural coreference model for high accuracy -- Provides fallback to custom spaCy-based resolution if needed +**Solution**: LLM-based fact extraction that: +- Resolves pronouns to actual referents during extraction +- Makes facts readable without original context +- Includes all relevant details (WHO, WHAT, WHERE, WHEN, WHY, HOW) +- Processes facts in parallel for speed **Result**: "Alice joined Google last year" - fully self-contained **Technology**: -- **FastCoref** - Fast, accurate neural coreference resolution -- Processes 2.8K documents in 25 seconds on GPU -- Significant speedup over sequential spaCy approach -- Fallback to custom spaCy implementation if needed +- LLM fact extraction with detailed prompts for pronoun resolution +- Structured output using Pydantic models +- Batch processing for efficiency ### LLM-Based Fact Extraction @@ -165,9 +166,8 @@ Raw content is processed through an LLM to extract meaningful facts before stora - `psycopg2-binary` - PostgreSQL client - `sentence-transformers` - Local embedding model (bge-small-en-v1.5) - `torch` - Deep learning framework (for embeddings) -- `fastcoref` - Fast neural coreference resolution - `spacy` - NLP (NER, dependency parsing, tokenization) -- `nltk` - Sentence tokenization +- `langchain-text-splitters` - Intelligent text chunking - `networkx` - Graph operations - `pyvis` - Interactive HTML graph visualization - `matplotlib` - Static graph visualization @@ -247,7 +247,7 @@ memory-poc/ ├── memory/ # Core memory system package │ ├── temporal_semantic_memory.py # Main memory system class │ ├── entity_resolver.py # Entity extraction and disambiguation -│ ├── coref_resolver.py # Coreference resolution +│ ├── llm_client.py # LLM-based fact extraction │ └── utils.py # Utility functions │ ├── demos/ # Demo scripts diff --git a/benchmarks/locomo/benchmark_results.json b/benchmarks/locomo/benchmark_results.json index ff79651b..408b16f8 100644 --- a/benchmarks/locomo/benchmark_results.json +++ b/benchmarks/locomo/benchmark_results.json @@ -1,18 +1,22 @@ { - "overall_accuracy": 33.33333333333333, - "total_correct": 1, - "total_questions": 3, + "overall_accuracy": 60.0, + "total_correct": 6, + "total_questions": 10, "conversation_results": [ { "sample_id": "conv-26", "metrics": { - "accuracy": 33.33333333333333, - "correct": 1, - "total": 3, + "accuracy": 60.0, + "correct": 6, + "total": 10, "category_stats": { + "1": { + "correct": 2, + "total": 3 + }, "2": { - "correct": 0, - "total": 2 + "correct": 3, + "total": 6 }, "3": { "correct": 1, @@ -20,30 +24,2319 @@ } }, "detailed_results": [ + { + "question": "What is Caroline's relationship status?", + "correct_answer": "Single", + "predicted_answer": "I don't know", + "reasoning": "The context does not provide any information about Caroline's current relationship status. It mentions a tough breakup in the past, but there is no indication of whether she is currently in a relationship or single.", + "category": 1, + "retrieved_memories": [ + { + "id": "0b5694e4-7c0b-422c-bed4-588d92fb067f", + "text": "Caroline has known her current friends for four years, having moved from her home country around 2019-06-09.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-09T19:55:00+00:00", + "weight": 0.5928971016147087, + "activation": 0.738161846289745, + "semantic_similarity": 0.7381618257592838, + "recency": 1.1144095709452762e-38, + "frequency": 2.0 + }, + { + "id": "43224c50-a69d-4d79-bda5-98253119a520", + "text": "Caroline expressed appreciation for her friendship with Melanie.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-17T13:50:00+00:00", + "weight": 0.5855437934744278, + "activation": 0.725906290831977, + "semantic_similarity": 0.7259063540827823, + "recency": 1.0781237162542037e-35, + "frequency": 2.0 + }, + { + "id": "1e910def-a7cb-4593-be18-99c833176fa3", + "text": "Caroline's gender transition and artistic expression have altered her relationships: some close friends continue to support her, while a few could not handle the changes; overall she feels happier and her relationships now feel more genuine.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-09-13T00:09:00+00:00", + "weight": 0.581743502522861, + "activation": 0.719572463048328, + "semantic_similarity": 0.7195725453612087, + "recency": 1.5153148641642148e-34, + "frequency": 2.0 + }, + { + "id": "7f5db464-eed6-4af6-b3bc-820f94193202", + "text": "Caroline feels lucky to have Melanie as a friend who reminds her of happy moments and supports her during life's struggles.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-17T13:50:00+00:00", + "weight": 0.5294705960529247, + "activation": 0.5807250326655816, + "semantic_similarity": 0.6841769541775008, + "recency": 1.078119636786517e-35, + "frequency": 2.0 + }, + { + "id": "de8d33ff-fe15-4f25-80f8-c534bc9ceb05", + "text": "Melanie and Caroline consider that they can always be there for each other, indicating a mutual supportive relationship.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-10-22T09:55:00+00:00", + "weight": 0.5256005666944299, + "activation": 0.5807250326655816, + "semantic_similarity": 0.6712768563158512, + "recency": 7.796889739732441e-33, + "frequency": 2.0 + }, + { + "id": "ad619ec1-c081-4fab-bb8f-707d8eed6fc0", + "text": "Caroline mentioned a tough breakup in the past and expressed thankfulness for her friends, family, and mentors who have supported her.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-09T19:55:00+00:00", + "weight": 0.5232549537202421, + "activation": 0.590529477031796, + "semantic_similarity": 0.6536537020356776, + "recency": 1.1144053544427697e-38, + "frequency": 2.0 + }, + { + "id": "aa36595e-58ca-42dc-b50d-8c785526bbf3", + "text": "Melanie's support has been meaningful to Caroline; Caroline feels grateful for Melanie's support throughout her journey and values being able to share and help others.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-10-22T09:55:00+00:00", + "weight": 0.520671892248089, + "activation": 0.5807250326655816, + "semantic_similarity": 0.6548479414947148, + "recency": 7.796889740120575e-33, + "frequency": 2.0 + }, + { + "id": "5e2c78a6-b363-44f7-a74b-23b7b61980f9", + "text": "Caroline has been looking into counseling or mental health work since her last conversation with Melanie, expressing passion for helping people, describing the work as tough but rewarding.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-06T20:18:00+00:00", + "weight": 0.5166050086282288, + "activation": 0.5807250326655816, + "semantic_similarity": 0.6412916627618478, + "recency": 1.6608494086599004e-37, + "frequency": 2.0 + }, + { + "id": "98c08619-7bb3-467c-a87e-027ee4b31021", + "text": "Both Caroline and Melanie affirmed their commitment to continue supporting each other, spreading love, acceptance, and hope, and to motivate each other through life's challenges.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-09T19:55:00+00:00", + "weight": 0.5154365483453377, + "activation": 0.590529477031796, + "semantic_similarity": 0.6275923507859963, + "recency": 1.1144053548684114e-38, + "frequency": 2.0 + }, + { + "id": "60fa2ddb-d241-4067-910e-ad8b864ac31b", + "text": "Melanie said that Caroline has always been there for her, and she appreciates their friendship.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-17T13:50:00+00:00", + "weight": 0.5153598866708379, + "activation": 0.5807250326655816, + "semantic_similarity": 0.6371412562372113, + "recency": 1.0781196367128996e-35, + "frequency": 2.0 + }, + { + "id": "d20a1038-61b6-4baa-9d6a-7d3a729434af", + "text": "Caroline expressed gratitude for the love and support she has received throughout her transition and aims to give a voice to the trans community.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-09T19:55:00+00:00", + "weight": 0.5147455739355009, + "activation": 0.590529477031796, + "semantic_similarity": 0.6252891027532071, + "recency": 1.1144053547845722e-38, + "frequency": 2.0 + }, + { + "id": "71e5a874-ce13-49df-a1a2-8f9fa377324c", + "text": "Caroline commented on Melanie's purple shoes, asking whether they are intended for walking or running.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-12T16:33:00+00:00", + "weight": 0.5136131344114743, + "activation": 0.5807250326655816, + "semantic_similarity": 0.6313187487059991, + "recency": 2.9793470414229446e-37, + "frequency": 2.0 + }, + { + "id": "73850c77-935b-45c3-9a68-3552e0f85121", + "text": "Caroline emphasizes that mental health is a priority and advises Melanie to take care of herself.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-12T16:33:00+00:00", + "weight": 0.5120275116131798, + "activation": 0.5807250326655816, + "semantic_similarity": 0.626033339378351, + "recency": 2.9793470416780796e-37, + "frequency": 2.0 + }, + { + "id": "50dd73e8-e477-4c45-b052-b3eae96a1a6a", + "text": "Melanie expressed pride in Caroline's work and said she is proud to be part of the difference Caroline is making.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-09T19:55:00+00:00", + "weight": 0.5110527232495037, + "activation": 0.590529477031796, + "semantic_similarity": 0.6129796004665498, + "recency": 1.1144053547510302e-38, + "frequency": 2.0 + }, + { + "id": "006df526-f850-48a9-a2f3-a13799f0391c", + "text": "Melanie states that the conversation with Caroline has been great for her mental health and she intends to continue the positive practices.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-12T16:33:00+00:00", + "weight": 0.5098334678141485, + "activation": 0.5807250326655816, + "semantic_similarity": 0.6187198600482468, + "recency": 2.9793470418677586e-37, + "frequency": 2.0 + }, + { + "id": "d4afd073-6eda-41ec-b138-8fc46c23bc23", + "text": "Caroline has not yet tried pottery but is interested in trying new art forms and may try pottery sometime in the future.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-09-13T00:09:00+00:00", + "weight": 0.5093245191024905, + "activation": 0.5756579704386624, + "semantic_similarity": 0.6220904265696393, + "recency": 1.5153019395586813e-34, + "frequency": 2.0 + }, + { + "id": "c7ffecc3-a614-401d-9f62-a23753c7ca5f", + "text": "Melanie has been reading a book that Caroline recommended a while ago and has been painting to keep busy.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-10-13T10:31:00+00:00", + "weight": 0.5082040688672157, + "activation": 0.5807250326655816, + "semantic_similarity": 0.6132885302251372, + "recency": 3.177913671815118e-33, + "frequency": 2.0 + }, + { + "id": "ff8318fb-cbb5-4f95-a985-da11cfb910df", + "text": "Caroline painted a piece after visiting an LGBTQ center, intending to capture the community's unity and strength; she shared this painting with Melanie on July 17, 2023.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-17T14:31:00+00:00", + "weight": 0.5053548330296247, + "activation": 0.5807250326655816, + "semantic_similarity": 0.6037910774331675, + "recency": 4.870691184975256e-37, + "frequency": 2.0 + }, + { + "id": "f62cd380-3b68-4116-b0b3-787ce4c96eac", + "text": "Caroline advised Melanie to research and find an adoption agency or lawyer, gather necessary documents such as references, financial information, and medical checks, and to prepare emotionally because the waiting period can be hard.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-10-13T10:31:00+00:00", + "weight": 0.5012917682997061, + "activation": 0.5807250326655816, + "semantic_similarity": 0.5902475283334387, + "recency": 3.177913672068922e-33, + "frequency": 2.0 + }, + { + "id": "a8b8baac-87de-4f41-b0c5-b32f2870f1d6", + "text": "Caroline is inspired by her work that makes a difference for the LGBTQ+ community, believing that helping create a more loving world is amazing, and this inspiration motivates her to keep making art.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-09-13T00:09:00+00:00", + "weight": 0.501231271249604, + "activation": 0.5756579704386624, + "semantic_similarity": 0.5951129337266843, + "recency": 1.5153019392219583e-34, + "frequency": 2.0 + } + ], + "is_correct": false, + "correctness_reasoning": "The predicted answer 'I don't know' does not state that Caroline is single, so it does not match the correct answer." + }, + { + "question": "When is Melanie planning on going camping?", + "correct_answer": "June 2023", + "predicted_answer": "I don't know", + "reasoning": "The context does not provide specific information about any future camping plans for Melanie. It mentions past camping trips and her family's enjoyment of camping, but there is no indication of when they are planning to go camping next.", + "category": 2, + "retrieved_memories": [ + { + "id": "d6fa6c91-b0b0-48c3-8dc6-a2981abaae82", + "text": "On 2023-07-15, Melanie and her family went on a camping trip in the forest.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-15T13:51:00+00:00", + "weight": 0.6385532224646773, + "activation": 0.81425535891285, + "semantic_similarity": 0.8142553826360744, + "recency": 3.976579229693862e-37, + "frequency": 2.0 + }, + { + "id": "1bcbab0e-f708-46f3-9191-4b591598a2df", + "text": "Melanie went camping with her family on the weekend of July 1\u20132, 2023, which was two weekends before the conversation date of July 17, 2023.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-01T14:31:00+00:00", + "weight": 0.6341995563735137, + "activation": 0.806999302744782, + "semantic_similarity": 0.8069992185002633, + "recency": 9.833400746436395e-38, + "frequency": 2.0 + }, + { + "id": "757040fe-bd93-4ed8-bbe2-731b6b33fb56", + "text": "Melanie went camping with her children a few weeks before September 13, 2023 (approximately on August 23, 2023), during which they explored the forest, hiked, and had a blast.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-23T00:09:00+00:00", + "weight": 0.610266205211061, + "activation": 0.767110319985189, + "semantic_similarity": 0.767110364051681, + "recency": 1.8555264197290307e-35, + "frequency": 2.0 + }, + { + "id": "8a78111e-a82b-478f-93d5-5256f4727402", + "text": "Melanie took her family camping in the mountains during the week prior to June 27, 2023 (last week), providing a nice time together.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-20T10:37:00+00:00", + "weight": 0.5694267831878538, + "activation": 0.65140428713028, + "semantic_similarity": 0.746684990162566, + "recency": 3.2204808252609967e-38, + "frequency": 2.0 + }, + { + "id": "fa88ef2c-bf7a-4349-9898-21d90bd4cda0", + "text": "Melanie's family looks forward to an annual summer camping trip, which they consider the highlight of their summer, as of July 20, 2023.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-20T20:56:00+00:00", + "weight": 0.5663847277711936, + "activation": 0.65140428713028, + "semantic_similarity": 0.7365448054403654, + "recency": 6.752627520291924e-37, + "frequency": 2.0 + }, + { + "id": "33bfbe46-a1b7-4119-8110-33f78643abe5", + "text": "During a family camping trip in August 2022, Melanie's family observed the Perseid meteor shower, made wishes, and felt awe while lying under a clear, star\u2011filled sky.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2022-08-12T20:56:00+00:00", + "weight": 0.5624554345902368, + "activation": 0.65140428713028, + "semantic_similarity": 0.7234471615038428, + "recency": 9.475486416300536e-52, + "frequency": 2.0 + }, + { + "id": "60116c77-ad6d-4038-a91e-ab7621a2f94f", + "text": "Melanie suggested doing a family outing this summer, proposing a group activity during the 2023 summer season.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-21T13:50:00+00:00", + "weight": 0.5620544578312987, + "activation": 0.65140428713028, + "semantic_similarity": 0.7221105723073825, + "recency": 3.607205789759941e-38, + "frequency": 2.0 + }, + { + "id": "2c65ccf4-14ae-4519-9a27-7af35209c634", + "text": "Melanie had a quiet weekend on July 8\u20139, 2023, the weekend immediately after the family camping trip, to relax and unplug.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-08T14:31:00+00:00", + "weight": 0.5614518383638576, + "activation": 0.65140428713028, + "semantic_similarity": 0.7201018407492454, + "recency": 1.980188230602638e-37, + "frequency": 2.0 + }, + { + "id": "dbc74f58-282c-441c-9b8a-9b729c6b0f15", + "text": "Melanie enjoys camping trips with her family because nature provides peace, serenity, and opportunities to bond over stories, campfires, birdsong, and fresh air, which refreshes her soul and helps her reset and recharge.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-10-20T18:55:00+00:00", + "weight": 0.5538515296521284, + "activation": 0.65140428713028, + "semantic_similarity": 0.6947674783768145, + "recency": 6.627240762789156e-33, + "frequency": 2.0 + }, + { + "id": "be729e0b-7a37-4fef-98c1-5da6390b128a", + "text": "Melanie painted a lake sunrise painting last year (2022-05-08), and the artwork is special to her.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2022-05-08T13:56:00+00:00", + "weight": 0.5442424851154435, + "activation": 0.65140428713028, + "semantic_similarity": 0.6627373299211983, + "recency": 6.233149802321527e-56, + "frequency": 2.0 + }, + { + "id": "1e8079c8-e0bf-4634-a94f-a3cc14de2542", + "text": "Melanie posted a recent picture taken on October 19, 2023, showing her children enjoying the Grand Canyon, which she described as a nice way to relax after the roadtrip.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-10-19T18:55:00+00:00", + "weight": 0.5442232136177595, + "activation": 0.65140428713028, + "semantic_similarity": 0.6626730915955849, + "recency": 5.996575421476561e-33, + "frequency": 2.0 + }, + { + "id": "f9c087ae-d272-4bfb-b111-fc538fd577fd", + "text": "On 2023-07-14, Melanie took her kids to a pottery workshop where they all made their own pots; the activity was fun and therapeutic, and the kids loved it, being excited to get their hands dirty and create something with clay.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-14T13:51:00+00:00", + "weight": 0.543724684777126, + "activation": 0.65140428713028, + "semantic_similarity": 0.6610113287934735, + "recency": 3.598129503171291e-37, + "frequency": 2.0 + }, + { + "id": "64621ccc-3569-43ab-bcbc-300752e4cba9", + "text": "On the weekend of 2023-07-08, Melanie and her kids painted a nature-inspired artwork together, which they described as their latest work.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-08T13:51:00+00:00", + "weight": 0.5436108257052754, + "activation": 0.65140428713028, + "semantic_similarity": 0.6606317985539714, + "recency": 1.9746953406449577e-37, + "frequency": 2.0 + }, + { + "id": "6cd22599-91e4-4777-8cea-136df2061405", + "text": "Melanie is currently swamped with caring for her kids and managing work responsibilities.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-05-08T13:56:00+00:00", + "weight": 0.541549458385559, + "activation": 0.65140428713028, + "semantic_similarity": 0.6537605741549166, + "recency": 4.430534817106696e-40, + "frequency": 2.0 + }, + { + "id": "e460bf87-7ca8-40cb-bb49-3750d164c90d", + "text": "Melanie spent August 24, 2023, volunteering with her family at a homeless shelter, observing neglected individuals and feeling that they made a positive difference.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-24T13:33:00+00:00", + "weight": 0.5405761492521944, + "activation": 0.65140428713028, + "semantic_similarity": 0.6505162103770347, + "recency": 2.1684094851390347e-35, + "frequency": 2.0 + }, + { + "id": "6ce7be9f-ef63-4d9f-9bce-fd223d501ee8", + "text": "Melanie finds peace through creativity and family support.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-15T13:51:00+00:00", + "weight": 0.5396226296575926, + "activation": 0.65140428713028, + "semantic_similarity": 0.6473378117283618, + "recency": 3.976548088225122e-37, + "frequency": 2.0 + }, + { + "id": "c1db0587-badf-4875-9b80-a3e2ad5a64ee", + "text": "Melanie shared a photograph of her family camping at the beach, stating that the experience brings her family closer together.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-06T20:18:00+00:00", + "weight": 0.5386915029894479, + "activation": 0.65140428713028, + "semantic_similarity": 0.6442340561678795, + "recency": 1.660782919341833e-37, + "frequency": 2.0 + }, + { + "id": "99533d0b-08a4-4bfb-ae6f-82ff14200c83", + "text": "Melanie has been married for five years, meaning she married her husband around 2018-06-09.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2018-06-09T19:55:00+00:00", + "weight": 0.5374705262130155, + "activation": 0.65140428713028, + "semantic_similarity": 0.6401641335797715, + "recency": 5.5571651502913045e-118, + "frequency": 2.0 + }, + { + "id": "6b0289f7-0dbc-4a51-8628-16d23a5991c1", + "text": "Melanie feels inspired by the autumn season and is planning to create several new paintings in the near future, as expressed on August 25, 2023.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-25T13:33:00+00:00", + "weight": 0.5371921049278133, + "activation": 0.65140428713028, + "semantic_similarity": 0.6392360626290977, + "recency": 2.3964631018378227e-35, + "frequency": 2.0 + }, + { + "id": "fb45c7ac-8079-4af6-bcf2-6ae9dd3ea1d4", + "text": "Melanie recently completed a landscape painting, which she shared during the conversation on August 25, 2023.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-25T13:33:00+00:00", + "weight": 0.5361437921894194, + "activation": 0.65140428713028, + "semantic_similarity": 0.6357416868344515, + "recency": 2.3964631016491878e-35, + "frequency": 2.0 + } + ], + "is_correct": false, + "correctness_reasoning": "The predicted answer 'I don't know' does not provide the required information 'June 2023' and therefore is not equivalent to the correct answer." + }, + { + "question": "When did Caroline give a speech at a school?", + "correct_answer": "The week before 9 June 2023", + "predicted_answer": "2023-06-02", + "reasoning": "The context explicitly states that Caroline delivered a school event talk about her transgender journey on 2023-06-02.", + "category": 2, + "retrieved_memories": [ + { + "id": "e4502529-fc39-465d-82b7-d56d0e56fde6", + "text": "Caroline delivered a school event talk about her transgender journey and encouraged students to get involved in the LGBTQ community; the event took place last week on 2023-06-02.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-02T19:55:00+00:00", + "weight": 0.6057134820306492, + "activation": 0.759522452382897, + "semantic_similarity": 0.759522487719267, + "recency": 5.534217638137463e-39, + "frequency": 2.0 + }, + { + "id": "95f094d7-70ed-4438-8026-da6e3dd6a571", + "text": "During the school event on 2023-06-02, Caroline felt powerful sharing her struggles and personal development since coming out, and observed that the audience related to her story and were inspired to become better allies.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-02T19:55:00+00:00", + "weight": 0.5996411386976285, + "activation": 0.749401882326492, + "semantic_similarity": 0.7494019133322697, + "recency": 5.534217636465764e-39, + "frequency": 2.0 + }, + { + "id": "ec88eee3-ba37-427f-9bf4-e0995d5fc61a", + "text": "On Friday, June 23, 2023, Caroline attended an LGBTQ+ counseling workshop where professionals discussed various therapeutic methods for working with transgender people and demonstrated passion for creating safe spaces for individuals like her.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-23T10:37:00+00:00", + "weight": 0.5552226440478177, + "activation": 0.6753710299288, + "semantic_similarity": 0.6753711168972591, + "recency": 4.3475615065288293e-38, + "frequency": 2.0 + }, + { + "id": "4dc1b6d9-cb36-4156-91eb-6e633ac75d64", + "text": "Caroline shared a photograph taken when she and Melanie met up last week; the photo was taken on 2023-06-02.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-02T19:55:00+00:00", + "weight": 0.5172251325700236, + "activation": 0.6076179619063176, + "semantic_similarity": 0.6164658133270943, + "recency": 5.534211300014424e-39, + "frequency": 2.0 + }, + { + "id": "c5161f91-693c-48a1-a288-ad149f8fc765", + "text": "Caroline attended an LGBTQ conference on 2023-07-10, two days before the reference date, where she met and connected with people who have experienced similar journeys, found the environment welcoming, felt totally accepted, and expressed gratitude for the community.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-10T16:33:00+00:00", + "weight": 0.5129628609491097, + "activation": 0.54029682394304, + "semantic_similarity": 0.6695793792206591, + "recency": 2.4393975389592374e-37, + "frequency": 2.0 + }, + { + "id": "22612de6-dda7-4df8-af30-5d488b1bdc10", + "text": "On 2023-07-14, Caroline attended a council meeting for adoption; she found it inspiring and emotional, observed many people wanting to create loving homes for children in need, and felt even more determined to adopt.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-14T13:51:00+00:00", + "weight": 0.5005418695471089, + "activation": 0.54029682394304, + "semantic_similarity": 0.628176074547323, + "recency": 3.5984424466313127e-37, + "frequency": 2.0 + }, + { + "id": "006df526-f850-48a9-a2f3-a13799f0391c", + "text": "Melanie states that the conversation with Caroline has been great for her mental health and she intends to continue the positive practices.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-12T16:33:00+00:00", + "weight": 0.4926971599924729, + "activation": 0.54029682394304, + "semantic_similarity": 0.6020270426985361, + "recency": 2.9794868813890685e-37, + "frequency": 2.0 + }, + { + "id": "a10ae2d0-45de-4fbb-8c37-9762142b5158", + "text": "As of July 17, 2023, Caroline is mentoring a transgender teen who shares her own gender identity, and together they are working on building confidence and developing positive coping strategies.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-17T14:31:00+00:00", + "weight": 0.4920764235358188, + "activation": 0.5054853867820114, + "semantic_similarity": 0.6347693583373847, + "recency": 4.870900738597122e-37, + "frequency": 2.0 + }, + { + "id": "50dd73e8-e477-4c45-b052-b3eae96a1a6a", + "text": "Melanie expressed pride in Caroline's work and said she is proud to be part of the difference Caroline is making.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-09T19:55:00+00:00", + "weight": 0.49152321091146134, + "activation": 0.54029682394304, + "semantic_similarity": 0.5981138790951646, + "recency": 1.11445329739746e-38, + "frequency": 2.0 + }, + { + "id": "63dd0bce-9e94-439c-a66b-2348579d05dc", + "text": "Caroline attended an LGBTQ+ pride parade, observed a happy crowd, felt a sense of belonging, and recognized significant growth in the LGBTQ+ community.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-26T13:36:00+00:00", + "weight": 0.4902385241685657, + "activation": 0.54029682394304, + "semantic_similarity": 0.5938315899521791, + "recency": 5.941992552736401e-38, + "frequency": 2.0 + }, + { + "id": "5f5ec14c-8715-4770-988a-6aa1fe4176f0", + "text": "Caroline attended an LGBTQ support group on 2023-05-07, finding the experience powerful.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-05-07T13:56:00+00:00", + "weight": 0.48909858660060834, + "activation": 0.49128755869399277, + "semantic_similarity": 0.639041063308035, + "recency": 4.009247628467812e-40, + "frequency": 2.0 + }, + { + "id": "f72607f8-5bf9-482e-ba74-f5ac97c15ac7", + "text": "The LGBTQ community experience showed Caroline how important it is to fight for trans rights and spread awareness.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-10T16:33:00+00:00", + "weight": 0.48869952969070274, + "activation": 0.54029682394304, + "semantic_similarity": 0.5887016083593024, + "recency": 2.4393975388943084e-37, + "frequency": 2.0 + }, + { + "id": "a4f20608-0fb6-4235-b47b-b64482d3e648", + "text": "Caroline stated her goal is to give kids a loving home, expressed gratitude for support from friends and mentors, and said she feels hopeful and optimistic about turning her adoption dream into reality.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-05-25T13:14:00+00:00", + "weight": 0.4880850435147672, + "activation": 0.54029682394304, + "semantic_similarity": 0.5866533211061841, + "recency": 2.418389539846299e-39, + "frequency": 2.0 + }, + { + "id": "88e28f0b-51b1-45bb-860b-4b1a734d3462", + "text": "Caroline reflected that volunteering reminded her of her own past struggles and feeling alone, and she was glad to share her story and offer support, feeling she could make a difference.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-28T15:19:00+00:00", + "weight": 0.4854217191260243, + "activation": 0.54029682394304, + "semantic_similarity": 0.5777755731437075, + "recency": 3.2590704712838855e-35, + "frequency": 2.0 + }, + { + "id": "05f1dcaa-6f99-46b5-87e9-d2efa64e01cd", + "text": "Caroline joined a mentorship program for LGBTQ youth on the weekend of July 15\u201316, 2023, aiming to support and empower young members of the community.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-15T14:31:00+00:00", + "weight": 0.4852769317696861, + "activation": 0.4948453757498368, + "semantic_similarity": 0.6227443968157836, + "recency": 3.987956229570448e-37, + "frequency": 2.0 + }, + { + "id": "c7ffecc3-a614-401d-9f62-a23753c7ca5f", + "text": "Melanie has been reading a book that Caroline recommended a while ago and has been painting to keep busy.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-10-13T10:31:00+00:00", + "weight": 0.4846367597711927, + "activation": 0.54029682394304, + "semantic_similarity": 0.5751590419609356, + "recency": 3.178062826735761e-33, + "frequency": 2.0 + }, + { + "id": "3f797cf0-1c31-4f25-8815-0791293e3bcd", + "text": "During her transition and journey toward self-acceptance, Caroline received invaluable help and encouragement from friends, family, and people she looked up to, which boosted her through tough times and helped her discover her true self.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-10-22T09:55:00+00:00", + "weight": 0.4830354920709111, + "activation": 0.54029682394304, + "semantic_similarity": 0.5698214829599971, + "recency": 7.797255689131378e-33, + "frequency": 2.0 + }, + { + "id": "f3fd8e60-f94c-4dad-9a29-358228690663", + "text": "Caroline plans to attend a transgender conference later this month, expressing excitement to meet community members and learn more about advocacy.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-03T13:36:00+00:00", + "weight": 0.48275036326470055, + "activation": 0.4959545664604603, + "semantic_similarity": 0.6132133110885414, + "recency": 1.1965703607295037e-37, + "frequency": 2.0 + }, + { + "id": "1a905e0b-4767-4a9e-b3ad-bc32d0657ab2", + "text": "Caroline says that her own personal journey and the support she received significantly improved her life; observing the benefits of counseling and support groups motivated her to care more about mental health, understand herself better, and create a safe, inviting environment for others to grow.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-27T10:37:00+00:00", + "weight": 0.48258318586340954, + "activation": 0.54029682394304, + "semantic_similarity": 0.5683137956016583, + "recency": 6.485792193876516e-38, + "frequency": 2.0 + }, + { + "id": "c15fad08-4a6a-4c55-9d80-696705c085c2", + "text": "Caroline and her mentee attended an LGBT pride event on June 17, 2023, where they experienced a supportive and loving atmosphere.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-17T14:31:00+00:00", + "weight": 0.481936534162537, + "activation": 0.47851202244483465, + "semantic_similarity": 0.6279430914302889, + "recency": 2.425078680378972e-38, + "frequency": 2.0 + } + ], + "is_correct": true, + "correctness_reasoning": "The predicted answer '2023-06-02' is exactly one week before 9 June 2023, matching the correct answer 'The week before 9 June 2023'." + }, + { + "question": "When did Melanie run a charity race?", + "correct_answer": "The sunday before 25 May 2023", + "predicted_answer": "May 20, 2023", + "reasoning": "The context explicitly states that Melanie ran a charity race for mental health on Saturday, May 20, 2023. This provides a clear and direct answer to the question.", + "category": 2, + "retrieved_memories": [ + { + "id": "96406bc5-690f-4f4e-ad4b-968a6648bbf1", + "text": "Melanie ran a charity race for mental health on Saturday, May 20, 2023, which she found rewarding and which made her think about the importance of taking care of one's mind.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-05-20T13:14:00+00:00", + "weight": 0.6080577995801428, + "activation": 0.76342961897166, + "semantic_similarity": 0.7634297129621495, + "recency": 1.4667843256884606e-39, + "frequency": 2.0 + }, + { + "id": "e460bf87-7ca8-40cb-bb49-3750d164c90d", + "text": "Melanie spent August 24, 2023, volunteering with her family at a homeless shelter, observing neglected individuals and feeling that they made a positive difference.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-24T13:33:00+00:00", + "weight": 0.5461861669634696, + "activation": 0.660310308327966, + "semantic_similarity": 0.6603102482169325, + "recency": 2.168534390799205e-35, + "frequency": 2.0 + }, + { + "id": "487ca766-c480-4748-ac1a-0362311fc948", + "text": "Melanie recently purchased new shoes, which are purple in color and intended for running.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-12T16:33:00+00:00", + "weight": 0.5379265600532386, + "activation": 0.646544314405968, + "semantic_similarity": 0.6465442191048271, + "recency": 2.9793993782823916e-37, + "frequency": 2.0 + }, + { + "id": "52c9bd89-9bd2-410a-9dd6-3e1ba3369b5d", + "text": "Caroline thanked Melanie for her encouraging words, said the support means a lot, and pledged to do her best to ensure any adopted children have a safe and loving home.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-05-25T13:14:00+00:00", + "weight": 0.5074708823773078, + "activation": 0.610743695177328, + "semantic_similarity": 0.5808259127470313, + "recency": 2.4183089332937094e-39, + "frequency": 2.0 + }, + { + "id": "312a4401-94ce-4509-94c4-f7f4481fcf83", + "text": "Melanie said she is carving out daily me-time that includes running, reading, or playing her violin, activities that refresh her and help her stay present for her family.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-05-25T13:14:00+00:00", + "weight": 0.5043215443688921, + "activation": 0.610743695177328, + "semantic_similarity": 0.5703281193856459, + "recency": 2.418308933545545e-39, + "frequency": 2.0 + }, + { + "id": "1b99342d-486f-4f1a-b1a1-1b0d94f3ded3", + "text": "Melanie stated that her husband and kids keep her motivated.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-09T19:55:00+00:00", + "weight": 0.5010528954816535, + "activation": 0.5282482466623728, + "semantic_similarity": 0.6419280716098056, + "recency": 1.1144119147535568e-38, + "frequency": 2.0 + }, + { + "id": "d6fa6c91-b0b0-48c3-8dc6-a2981abaae82", + "text": "On 2023-07-15, Melanie and her family went on a camping trip in the forest.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-15T13:51:00+00:00", + "weight": 0.5002171240450245, + "activation": 0.5282482466623728, + "semantic_similarity": 0.6391421668210422, + "recency": 3.976761380451225e-37, + "frequency": 2.0 + }, + { + "id": "6ce7be9f-ef63-4d9f-9bce-fd223d501ee8", + "text": "Melanie finds peace through creativity and family support.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-15T13:51:00+00:00", + "weight": 0.49682061678436584, + "activation": 0.5282482466623728, + "semantic_similarity": 0.6278204759521799, + "recency": 3.976761379816073e-37, + "frequency": 2.0 + }, + { + "id": "35ea25a2-0e9d-4e01-ae30-7655ca3d4c44", + "text": "The concert Melanie attended on 2023-08-13 featured performer Matt Patterson, whose voice and songs she described as amazing and talented.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-13T14:24:00+00:00", + "weight": 0.495634289319396, + "activation": 0.5282482466623728, + "semantic_similarity": 0.6238660510689472, + "recency": 7.243978255284424e-36, + "frequency": 2.0 + }, + { + "id": "d8d3b55e-b418-4ea0-886a-d4c0f8feef62", + "text": "Melanie shared a picture taken on 2023-08-13 showing many people having a blast at the concert, reminding her of the importance of cultivating a loving and accepting environment for her children.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-13T14:24:00+00:00", + "weight": 0.4955201613237674, + "activation": 0.5282482466623728, + "semantic_similarity": 0.6234856244168518, + "recency": 7.243978255577915e-36, + "frequency": 2.0 + }, + { + "id": "99533d0b-08a4-4bfb-ae6f-82ff14200c83", + "text": "Melanie has been married for five years, meaning she married her husband around 2018-06-09.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2018-06-09T19:55:00+00:00", + "weight": 0.49343939367036094, + "activation": 0.5282482466623728, + "semantic_similarity": 0.6165497322388304, + "recency": 5.557442803148722e-118, + "frequency": 2.0 + }, + { + "id": "6cd22599-91e4-4777-8cea-136df2061405", + "text": "Melanie is currently swamped with caring for her kids and managing work responsibilities.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-05-08T13:56:00+00:00", + "weight": 0.4929780369843564, + "activation": 0.5282482466623728, + "semantic_similarity": 0.6150118766188151, + "recency": 4.430739346790953e-40, + "frequency": 2.0 + }, + { + "id": "50dd73e8-e477-4c45-b052-b3eae96a1a6a", + "text": "Melanie expressed pride in Caroline's work and said she is proud to be part of the difference Caroline is making.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-09T19:55:00+00:00", + "weight": 0.49254514957772355, + "activation": 0.5282482466623728, + "semantic_similarity": 0.6135689185967056, + "recency": 1.1144161503627e-38, + "frequency": 2.0 + }, + { + "id": "757040fe-bd93-4ed8-bbe2-731b6b33fb56", + "text": "Melanie went camping with her children a few weeks before September 13, 2023 (approximately on August 23, 2023), during which they explored the forest, hiked, and had a blast.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-23T00:09:00+00:00", + "weight": 0.49111653757489904, + "activation": 0.5282482466623728, + "semantic_similarity": 0.6088068785872908, + "recency": 1.855604365068456e-35, + "frequency": 2.0 + }, + { + "id": "f9c087ae-d272-4bfb-b111-fc538fd577fd", + "text": "On 2023-07-14, Melanie took her kids to a pottery workshop where they all made their own pots; the activity was fun and therapeutic, and the kids loved it, being excited to get their hands dirty and create something with clay.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-14T13:51:00+00:00", + "weight": 0.4909032205325806, + "activation": 0.5282482466623728, + "semantic_similarity": 0.6080958217795625, + "recency": 3.598322500348928e-37, + "frequency": 2.0 + }, + { + "id": "e21e9110-0c25-415b-a959-a21eb72d8a4b", + "text": "Melanie once fed a horse a carrot.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-23T15:31:00+00:00", + "weight": 0.4908149382345375, + "activation": 0.5282482466623728, + "semantic_similarity": 0.6078015474527522, + "recency": 1.9783006598182982e-35, + "frequency": 2.0 + }, + { + "id": "a18b044a-2586-45b9-93d1-3360db92e821", + "text": "Melanie uses painting as a fun way to express her feelings, get creative, and relax after a long day.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-05-08T13:56:00+00:00", + "weight": 0.49081204805059286, + "activation": 0.610743695177328, + "semantic_similarity": 0.5252964649913149, + "recency": 4.430756193083742e-40, + "frequency": 2.0 + }, + { + "id": "64621ccc-3569-43ab-bcbc-300752e4cba9", + "text": "On the weekend of 2023-07-08, Melanie and her kids painted a nature-inspired artwork together, which they described as their latest work.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-08T13:51:00+00:00", + "weight": 0.49078994519644037, + "activation": 0.5282482466623728, + "semantic_similarity": 0.6077182373257619, + "recency": 1.974793753559377e-37, + "frequency": 2.0 + }, + { + "id": "54526f1d-bc1e-4eb1-96e9-d0bbe6c3e56e", + "text": "Melanie celebrated her daughter's birthday with a concert on the evening of 2023-08-13, featuring music, joy, and a warm summer breeze; she observed her kids' smiles and expressed thankfulness for these special moments.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-13T14:24:00+00:00", + "weight": 0.4906547525976461, + "activation": 0.5282482466623728, + "semantic_similarity": 0.6072675953297808, + "recency": 7.243978254990933e-36, + "frequency": 2.0 + }, + { + "id": "6fb4ae9a-e9aa-4284-ae34-c5a157b98fcc", + "text": "Melanie stated that her family is her biggest motivation and support, giving her strength to keep going.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-10-14T18:55:00+00:00", + "weight": 0.48920699159952397, + "activation": 0.5282482466623728, + "semantic_similarity": 0.6024417253360405, + "recency": 3.637288558995905e-33, + "frequency": 2.0 + } + ], + "is_correct": false, + "correctness_reasoning": "The correct answer specifies \"the Sunday before 25 May 2023,\" which is 21 May 2023. The predicted answer gives May 20, 2023 (a Saturday), so they are not equivalent." + }, { "question": "When did Caroline go to the LGBTQ support group?", "correct_answer": "7 May 2023", - "predicted_answer": "Caroline attended the LGBTQ support group yesterday.", + "predicted_answer": "2023-05-07", + "reasoning": "The context explicitly states that Caroline attended an LGBTQ support group on 2023-05-07, providing a clear answer to the question.", "category": 2, - "is_correct": false + "retrieved_memories": [ + { + "id": "5f5ec14c-8715-4770-988a-6aa1fe4176f0", + "text": "Caroline attended an LGBTQ support group on 2023-05-07, finding the experience powerful.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-05-07T13:56:00+00:00", + "weight": 0.6796956536236841, + "activation": 0.882826116169278, + "semantic_similarity": 0.8828260625763358, + "recency": 4.009011402269459e-40, + "frequency": 2.0 + }, + { + "id": "3a2f0dfc-4fc1-4986-9474-ce54481550a3", + "text": "Caroline joined a new LGBTQ activist group called Connected LGBTQ Activists on Tuesday, July 18, 2023.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-18T20:56:00+00:00", + "weight": 0.6497555047258308, + "activation": 0.832925821331913, + "semantic_similarity": 0.832925861087523, + "recency": 5.528718569948636e-37, + "frequency": 2.0 + }, + { + "id": "72855141-35e9-47cd-92aa-5d1ffb89ae3a", + "text": "The LGBTQ support group made Caroline feel accepted and gave her courage to embrace herself.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-05-08T13:56:00+00:00", + "weight": 0.6274170101632144, + "activation": 0.795695054274503, + "semantic_similarity": 0.7956949796028784, + "recency": 4.43064281101677e-40, + "frequency": 2.0 + }, + { + "id": "c5161f91-693c-48a1-a288-ad149f8fc765", + "text": "Caroline attended an LGBTQ conference on 2023-07-10, two days before the reference date, where she met and connected with people who have experienced similar journeys, found the environment welcoming, felt totally accepted, and expressed gratitude for the community.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-10T16:33:00+00:00", + "weight": 0.600047675078097, + "activation": 0.7062608929354224, + "semantic_similarity": 0.7938980239915674, + "recency": 2.4392508031077425e-37, + "frequency": 2.0 + }, + { + "id": "ec88eee3-ba37-427f-9bf4-e0995d5fc61a", + "text": "On Friday, June 23, 2023, Caroline attended an LGBTQ+ counseling workshop where professionals discussed various therapeutic methods for working with transgender people and demonstrated passion for creating safe spaces for individuals like her.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-23T10:37:00+00:00", + "weight": 0.598690975861133, + "activation": 0.7062608929354224, + "semantic_similarity": 0.789375693268354, + "recency": 4.3472950109126337e-38, + "frequency": 2.0 + }, + { + "id": "63dd0bce-9e94-439c-a66b-2348579d05dc", + "text": "Caroline attended an LGBTQ+ pride parade, observed a happy crowd, felt a sense of belonging, and recognized significant growth in the LGBTQ+ community.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-26T13:36:00+00:00", + "weight": 0.5832675302614079, + "activation": 0.7062608929354224, + "semantic_similarity": 0.7379642079359373, + "recency": 5.941635134168808e-38, + "frequency": 2.0 + }, + { + "id": "f72607f8-5bf9-482e-ba74-f5ac97c15ac7", + "text": "The LGBTQ community experience showed Caroline how important it is to fight for trans rights and spread awareness.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-10T16:33:00+00:00", + "weight": 0.5811890862685835, + "activation": 0.7062608929354224, + "semantic_similarity": 0.7310360612931892, + "recency": 2.439250805417151e-37, + "frequency": 2.0 + }, + { + "id": "453f811d-9535-42e7-8784-7a0eb35362ba", + "text": "During the June 17, 2023 LGBT pride event, Caroline recalls that the best moment was seeing her mentee's face light up upon witnessing the community's support.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-17T14:31:00+00:00", + "weight": 0.5757488452699021, + "activation": 0.7062608929354224, + "semantic_similarity": 0.7129019246309181, + "recency": 2.4249328050903984e-38, + "frequency": 2.0 + }, + { + "id": "c8ae7b11-e6b1-4360-9c03-7a265411447f", + "text": "The group Connected LGBTQ Activists, which Caroline joined, is composed of diverse members investing in positive changes, holds regular meetings, and plans events and campaigns to support each other, as described on July 20, 2023.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-20T20:56:00+00:00", + "weight": 0.5706201879423725, + "activation": 0.6663406570655304, + "semantic_similarity": 0.7357266360757113, + "recency": 6.752783785716208e-37, + "frequency": 2.0 + }, + { + "id": "05f1dcaa-6f99-46b5-87e9-d2efa64e01cd", + "text": "Caroline joined a mentorship program for LGBTQ youth on the weekend of July 15\u201316, 2023, aiming to support and empower young members of the community.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-15T14:31:00+00:00", + "weight": 0.5674557696440229, + "activation": 0.6089139880927572, + "semantic_similarity": 0.7826052440539858, + "recency": 3.9877163420957654e-37, + "frequency": 2.0 + }, + { + "id": "c15fad08-4a6a-4c55-9d80-696705c085c2", + "text": "Caroline and her mentee attended an LGBT pride event on June 17, 2023, where they experienced a supportive and loving atmosphere.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-17T14:31:00+00:00", + "weight": 0.5674245686658036, + "activation": 0.6096885261040705, + "semantic_similarity": 0.7817267027819415, + "recency": 2.424932805009003e-38, + "frequency": 2.0 + }, + { + "id": "22612de6-dda7-4df8-af30-5d488b1bdc10", + "text": "On 2023-07-14, Caroline attended a council meeting for adoption; she found it inspiring and emotional, observed many people wanting to create loving homes for children in need, and felt even more determined to adopt.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-14T13:51:00+00:00", + "weight": 0.5658305569267591, + "activation": 0.7062608929354224, + "semantic_similarity": 0.6798409634871081, + "recency": 3.5982259920890336e-37, + "frequency": 2.0 + }, + { + "id": "aa36595e-58ca-42dc-b50d-8c785526bbf3", + "text": "Melanie's support has been meaningful to Caroline; Caroline feels grateful for Melanie's support throughout her journey and values being able to share and help others.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-10-22T09:55:00+00:00", + "weight": 0.5543802248372177, + "activation": 0.7062608929354224, + "semantic_similarity": 0.6416731898553034, + "recency": 7.796786674122317e-33, + "frequency": 2.0 + }, + { + "id": "3f797cf0-1c31-4f25-8815-0791293e3bcd", + "text": "During her transition and journey toward self-acceptance, Caroline received invaluable help and encouragement from friends, family, and people she looked up to, which boosted her through tough times and helped her discover her true self.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-10-22T09:55:00+00:00", + "weight": 0.5483398419787363, + "activation": 0.7062608929354224, + "semantic_similarity": 0.6215385803270321, + "recency": 7.796786674402086e-33, + "frequency": 2.0 + }, + { + "id": "88e28f0b-51b1-45bb-860b-4b1a734d3462", + "text": "Caroline reflected that volunteering reminded her of her own past struggles and feeling alone, and she was glad to share her story and offer support, feeling she could make a difference.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-28T15:19:00+00:00", + "weight": 0.5473932926751475, + "activation": 0.7062608929354224, + "semantic_similarity": 0.6183834159817357, + "recency": 3.258874434261174e-35, + "frequency": 2.0 + }, + { + "id": "1a905e0b-4767-4a9e-b3ad-bc32d0657ab2", + "text": "Caroline says that her own personal journey and the support she received significantly improved her life; observing the benefits of counseling and support groups motivated her to care more about mental health, understand herself better, and create a safe, inviting environment for others to grow.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-27T10:37:00+00:00", + "weight": 0.5473810399227539, + "activation": 0.7062608929354224, + "semantic_similarity": 0.6183425734737571, + "recency": 6.485402065039465e-38, + "frequency": 2.0 + }, + { + "id": "a4f20608-0fb6-4235-b47b-b64482d3e648", + "text": "Caroline stated her goal is to give kids a loving home, expressed gratitude for support from friends and mentors, and said she feels hopeful and optimistic about turning her adoption dream into reality.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-05-25T13:14:00+00:00", + "weight": 0.54652741823091, + "activation": 0.7062608929354224, + "semantic_similarity": 0.6154971678342778, + "recency": 2.4182440707207888e-39, + "frequency": 2.0 + }, + { + "id": "50dd73e8-e477-4c45-b052-b3eae96a1a6a", + "text": "Melanie expressed pride in Caroline's work and said she is proud to be part of the difference Caroline is making.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-09T19:55:00+00:00", + "weight": 0.5463333678377977, + "activation": 0.7062608929354224, + "semantic_similarity": 0.61485033319057, + "recency": 1.1143862616477157e-38, + "frequency": 2.0 + }, + { + "id": "45907243-354f-45f5-9bd6-61199272b94e", + "text": "Caroline is organizing an LGBTQ art show scheduled for September 2023 (specifically around September 25, 2023) to exhibit her paintings and promote understanding and acceptance within the community.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-09-25T13:33:00+00:00", + "weight": 0.5424624381226976, + "activation": 0.5546027376588833, + "semantic_similarity": 0.7536053894167751, + "recency": 5.3197997659606686e-34, + "frequency": 2.0 + }, + { + "id": "d34361a2-3e61-4679-8516-7de3a31de2a8", + "text": "Caroline volunteered at an LGBTQ+ youth center, found it gratifying to talk to similar young people, and it reminded her of how essential it is to be kind and show support.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-28T15:19:00+00:00", + "weight": 0.5378260542978969, + "activation": 0.5650087143483379, + "semantic_similarity": 0.7277447999779849, + "recency": 3.2588642110786975e-35, + "frequency": 2.0 + } + ], + "is_correct": true, + "correctness_reasoning": "The predicted answer 2023-05-07 represents the same date as 7 May 2023, just in ISO format, so it is equivalent to the correct answer." }, { "question": "When did Melanie paint a sunrise?", "correct_answer": 2022, - "predicted_answer": "I don't know.", + "predicted_answer": "2022-05-08", + "reasoning": "The context explicitly states that Melanie painted a lake sunrise painting last year on 2022-05-08. This directly answers the question about when she painted a sunrise.", "category": 2, - "is_correct": false + "retrieved_memories": [ + { + "id": "be729e0b-7a37-4fef-98c1-5da6390b128a", + "text": "Melanie painted a lake sunrise painting last year (2022-05-08), and the artwork is special to her.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2022-05-08T13:56:00+00:00", + "weight": 0.649579216254692, + "activation": 0.832632040004971, + "semantic_similarity": 0.8326320141773355, + "recency": 6.233113001978623e-56, + "frequency": 2.0 + }, + { + "id": "74c1a0a2-91c5-4724-8b8e-84d3d2a1492f", + "text": "Melanie created a painting on 2023-10-06 that was inspired by sunsets; the colors of the painting make her feel calm.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-10-06T10:31:00+00:00", + "weight": 0.6319213512865487, + "activation": 0.803202224064072, + "semantic_similarity": 0.8032022802244235, + "recency": 1.578038526900449e-33, + "frequency": 2.0 + }, + { + "id": "7d96e021-b14a-4ecd-adb2-3036aeac918a", + "text": "Melanie recently painted a horse, creating a painting that she shared in a photo.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-23T15:31:00+00:00", + "weight": 0.5858844971979617, + "activation": 0.726474090008383, + "semantic_similarity": 0.7264742339848227, + "recency": 1.9781976575661012e-35, + "frequency": 2.0 + }, + { + "id": "fb45c7ac-8079-4af6-bcf2-6ae9dd3ea1d4", + "text": "Melanie recently completed a landscape painting, which she shared during the conversation on August 25, 2023.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-25T13:33:00+00:00", + "weight": 0.5676932504481701, + "activation": 0.6661056320039769, + "semantic_similarity": 0.7262052028232568, + "recency": 2.3964478024196726e-35, + "frequency": 2.0 + }, + { + "id": "64621ccc-3569-43ab-bcbc-300752e4cba9", + "text": "On the weekend of 2023-07-08, Melanie and her kids painted a nature-inspired artwork together, which they described as their latest work.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-08T13:51:00+00:00", + "weight": 0.5674790675852099, + "activation": 0.6661056320039769, + "semantic_similarity": 0.7254912599467229, + "recency": 1.9746827385360728e-37, + "frequency": 2.0 + }, + { + "id": "92a5a070-fa23-4903-ad73-660b7940181b", + "text": "In her sunset\u2011inspired painting, Melanie intentionally used peaceful blue streaks to convey tranquility, noting that the color blue calms her and that she wanted a serene vibe combined with vibrant colors.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-10-06T10:31:00+00:00", + "weight": 0.5589249296518987, + "activation": 0.6661056320039769, + "semantic_similarity": 0.6969774668356853, + "recency": 1.5780265930621085e-33, + "frequency": 2.0 + }, + { + "id": "b1a619f5-f467-428e-a84f-e6a48bee33e5", + "text": "Melanie and her children completed another collaborative painting, similar to a previous work, on July 17, 2023.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-17T14:31:00+00:00", + "weight": 0.5537432899118439, + "activation": 0.6661056320039769, + "semantic_similarity": 0.679705334368836, + "recency": 4.870446048270206e-37, + "frequency": 2.0 + }, + { + "id": "eb32a52f-791a-42dc-8476-a542e84d2a71", + "text": "Melanie's favorite artistic activities are painting landscapes and still life, which she appreciates for their depiction of nature, as she mentioned on August 25, 2023.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-25T13:33:00+00:00", + "weight": 0.552060742248721, + "activation": 0.6661056320039769, + "semantic_similarity": 0.6740968421584266, + "recency": 2.3964396354115454e-35, + "frequency": 2.0 + }, + { + "id": "ca9d8d15-1560-4823-936d-79be60dfb4f9", + "text": "Melanie has been involved in art for seven years and has recently identified painting and pottery as her primary muses.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-09-13T00:09:00+00:00", + "weight": 0.5478093718537007, + "activation": 0.6661056320039769, + "semantic_similarity": 0.6599256075083587, + "recency": 1.515227697180664e-34, + "frequency": 2.0 + }, + { + "id": "f9c087ae-d272-4bfb-b111-fc538fd577fd", + "text": "On 2023-07-14, Melanie took her kids to a pottery workshop where they all made their own pots; the activity was fun and therapeutic, and the kids loved it, being excited to get their hands dirty and create something with clay.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-14T13:51:00+00:00", + "weight": 0.5477892165130516, + "activation": 0.6661056320039769, + "semantic_similarity": 0.6598584230395286, + "recency": 3.598106543018016e-37, + "frequency": 2.0 + }, + { + "id": "c7ffecc3-a614-401d-9f62-a23753c7ca5f", + "text": "Melanie has been reading a book that Caroline recommended a while ago and has been painting to keep busy.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-10-13T10:31:00+00:00", + "weight": 0.5473645916854543, + "activation": 0.6661056320039769, + "semantic_similarity": 0.6584430069475373, + "recency": 3.177755324011146e-33, + "frequency": 2.0 + }, + { + "id": "ff8318fb-cbb5-4f95-a985-da11cfb910df", + "text": "Caroline painted a piece after visiting an LGBTQ center, intending to capture the community's unity and strength; she shared this painting with Melanie on July 17, 2023.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-17T14:31:00+00:00", + "weight": 0.5463288420862615, + "activation": 0.6661056320039769, + "semantic_similarity": 0.6549905082835616, + "recency": 4.8704460485521115e-37, + "frequency": 2.0 + }, + { + "id": "6ce7be9f-ef63-4d9f-9bce-fd223d501ee8", + "text": "Melanie finds peace through creativity and family support.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-15T13:51:00+00:00", + "weight": 0.5458624279050149, + "activation": 0.6661056320039769, + "semantic_similarity": 0.6534357943460729, + "recency": 3.976522710008435e-37, + "frequency": 2.0 + }, + { + "id": "33bfbe46-a1b7-4119-8110-33f78643abe5", + "text": "During a family camping trip in August 2022, Melanie's family observed the Perseid meteor shower, made wishes, and felt awe while lying under a clear, star\u2011filled sky.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2022-08-12T20:56:00+00:00", + "weight": 0.5424828580079306, + "activation": 0.6661056320039769, + "semantic_similarity": 0.6421705613557918, + "recency": 9.475391120595462e-52, + "frequency": 2.0 + }, + { + "id": "6b0289f7-0dbc-4a51-8628-16d23a5991c1", + "text": "Melanie feels inspired by the autumn season and is planning to create several new paintings in the near future, as expressed on August 25, 2023.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-25T13:33:00+00:00", + "weight": 0.5421374526811097, + "activation": 0.6661056320039769, + "semantic_similarity": 0.6410192102663889, + "recency": 2.3964396346432544e-35, + "frequency": 2.0 + }, + { + "id": "8064be3c-0593-4421-b4b5-b3aadffaebfc", + "text": "Melanie also produced an abstract painting and says she loves how art allows her to release her emotions.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-10-13T10:31:00+00:00", + "weight": 0.5409897524410486, + "activation": 0.6661056320039769, + "semantic_similarity": 0.6371935427995187, + "recency": 3.1777553241325774e-33, + "frequency": 2.0 + }, + { + "id": "d8d3b55e-b418-4ea0-886a-d4c0f8feef62", + "text": "Melanie shared a picture taken on 2023-08-13 showing many people having a blast at the concert, reminding her of the importance of cultivating a loving and accepting environment for her children.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-13T14:24:00+00:00", + "weight": 0.5392727580067038, + "activation": 0.6661056320039769, + "semantic_similarity": 0.6314702280183694, + "recency": 7.243571021106428e-36, + "frequency": 2.0 + }, + { + "id": "e3463e52-1b17-4a7a-b548-e5ccde5a4e2a", + "text": "Melanie created a pottery plate in her pottery class on August 24, 2023.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-24T13:33:00+00:00", + "weight": 0.539217989521479, + "activation": 0.6661056320039769, + "semantic_similarity": 0.6312876664009535, + "recency": 2.168395641871343e-35, + "frequency": 2.0 + }, + { + "id": "99533d0b-08a4-4bfb-ae6f-82ff14200c83", + "text": "Melanie has been married for five years, meaning she married her husband around 2018-06-09.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2018-06-09T19:55:00+00:00", + "weight": 0.5364959624660652, + "activation": 0.6661056320039769, + "semantic_similarity": 0.6222142428829073, + "recency": 5.557090313333293e-118, + "frequency": 2.0 + }, + { + "id": "d6fa6c91-b0b0-48c3-8dc6-a2981abaae82", + "text": "On 2023-07-15, Melanie and her family went on a camping trip in the forest.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-15T13:51:00+00:00", + "weight": 0.5359886032130999, + "activation": 0.6661056320039769, + "semantic_similarity": 0.6205230453730228, + "recency": 3.976522710500861e-37, + "frequency": 2.0 + } + ], + "is_correct": true, + "correctness_reasoning": "The predicted answer '2022-05-08' includes the year 2022, which matches the correct answer. The extra specificity does not contradict the required information, so the answers are equivalent." }, { "question": "What fields would Caroline be likely to pursue in her educaton?", "correct_answer": "Psychology, counseling certification", - "predicted_answer": "Caroline would be likely to pursue fields in counseling or mental health.", + "predicted_answer": "Counseling and mental health", + "reasoning": "The context provides multiple statements indicating Caroline's interest in pursuing a career in counseling and mental health. She has been actively researching these fields, plans to specialize in working with transgender individuals, and has expressed a desire to help others who have faced similar challenges. Therefore, it is clear that these are the fields she is likely to pursue in her education.", "category": 3, - "is_correct": true + "retrieved_memories": [ + { + "id": "5819027e-8dda-4d6c-aecf-696e998337c2", + "text": "Caroline plans to continue her education and explore career options, expressing excitement about the prospect.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-05-08T13:56:00+00:00", + "weight": 0.6333278909006648, + "activation": 0.805546402931213, + "semantic_similarity": 0.8055465667376696, + "recency": 4.430686961864207e-40, + "frequency": 2.0 + }, + { + "id": "eeb4a464-dc3f-4123-a16e-bfa95dedf0ea", + "text": "Caroline has recently been researching a career in counseling and mental health because she wants to help people who have experienced similar challenges to her own.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-27T10:37:00+00:00", + "weight": 0.5878932463286886, + "activation": 0.729822131416549, + "semantic_similarity": 0.7298220230124131, + "recency": 6.485474681344336e-38, + "frequency": 2.0 + }, + { + "id": "c759737b-8fff-4941-8c74-c832339e7595", + "text": "Caroline is actively researching and considering career options in counseling and mental health because she believes it is important for people to have someone to talk to and wants to help make that happen.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-12T16:33:00+00:00", + "weight": 0.582146898172474, + "activation": 0.720244824886322, + "semantic_similarity": 0.7202448356885913, + "recency": 2.9793410177962352e-37, + "frequency": 2.0 + }, + { + "id": "280b9bd7-1ed9-4a8a-b169-89af4775ae9b", + "text": "Caroline is keen on becoming a counselor or working in mental health so she can support people who face similar issues.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-05-08T13:56:00+00:00", + "weight": 0.5574724976051302, + "activation": 0.6444371223449705, + "semantic_similarity": 0.7138045363387968, + "recency": 4.43068163950985e-40, + "frequency": 2.0 + }, + { + "id": "bf146ef5-5001-4773-af33-8ab30c2b167f", + "text": "Caroline plans to specialize in working with transgender individuals, aiming to help them accept themselves and support their mental health.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-27T10:37:00+00:00", + "weight": 0.5190508116640551, + "activation": 0.5838577051332392, + "semantic_similarity": 0.646311667080278, + "recency": 6.485466888248173e-38, + "frequency": 2.0 + }, + { + "id": "05f1dcaa-6f99-46b5-87e9-d2efa64e01cd", + "text": "Caroline joined a mentorship program for LGBTQ youth on the weekend of July 15\u201316, 2023, aiming to support and empower young members of the community.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-15T14:31:00+00:00", + "weight": 0.5110870124043192, + "activation": 0.5761958599090576, + "semantic_similarity": 0.6274275147720062, + "recency": 3.987756193524277e-37, + "frequency": 2.0 + }, + { + "id": "a10ae2d0-45de-4fbb-8c37-9762142b5158", + "text": "As of July 17, 2023, Caroline is mentoring a transgender teen who shares her own gender identity, and together they are working on building confidence and developing positive coping strategies.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-17T14:31:00+00:00", + "weight": 0.5098787746974163, + "activation": 0.5761958599090576, + "semantic_similarity": 0.6234000557489967, + "recency": 4.870656422564771e-37, + "frequency": 2.0 + }, + { + "id": "1a905e0b-4767-4a9e-b3ad-bc32d0657ab2", + "text": "Caroline says that her own personal journey and the support she received significantly improved her life; observing the benefits of counseling and support groups motivated her to care more about mental health, understand herself better, and create a safe, inviting environment for others to grow.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-27T10:37:00+00:00", + "weight": 0.509216984880943, + "activation": 0.5838577051332392, + "semantic_similarity": 0.6135322444699044, + "recency": 6.485466888090481e-38, + "frequency": 2.0 + }, + { + "id": "72855141-35e9-47cd-92aa-5d1ffb89ae3a", + "text": "The LGBTQ support group made Caroline feel accepted and gave her courage to embrace herself.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-05-08T13:56:00+00:00", + "weight": 0.5076642422722653, + "activation": 0.6444371223449705, + "semantic_similarity": 0.5477770185625805, + "recency": 4.430681638150903e-40, + "frequency": 2.0 + }, + { + "id": "5477179a-380b-4266-8c50-a88d995c574a", + "text": "Caroline found the transgender stories shared at the LGBTQ support group inspiring, and she felt happy and thankful for the support she received.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-05-08T13:56:00+00:00", + "weight": 0.5044990900556001, + "activation": 0.6444371223449705, + "semantic_similarity": 0.5372265111736967, + "recency": 4.430681638263671e-40, + "frequency": 2.0 + }, + { + "id": "83e62a1b-74b9-40e2-b6d8-e4d9dab557a6", + "text": "Caroline received a necklace as a gift from her grandmother in Sweden when she was young; the necklace symbolizes love, faith, and strength and serves as a reminder of her roots and the love and support she receives from her family.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-27T10:37:00+00:00", + "weight": 0.4990035365793578, + "activation": 0.5838577051332392, + "semantic_similarity": 0.5794874167979536, + "recency": 6.485466888405682e-38, + "frequency": 2.0 + }, + { + "id": "73850c77-935b-45c3-9a68-3552e0f85121", + "text": "Caroline emphasizes that mental health is a priority and advises Melanie to take care of herself.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-12T16:33:00+00:00", + "weight": 0.4945876133452587, + "activation": 0.5761958599090576, + "semantic_similarity": 0.5724295179084713, + "recency": 2.9793374327131804e-37, + "frequency": 2.0 + }, + { + "id": "55adbb21-7685-4f71-8e02-e1b1e8a7c0b9", + "text": "Caroline intends to continue volunteering at the LGBTQ+ youth center, considers it an important part of her life, has made strong connections with people there, believes in community and supporting each other, and wants to keep making a difference.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-28T15:19:00+00:00", + "weight": 0.49254106871292913, + "activation": 0.48033283357744794, + "semantic_similarity": 0.6614707287989824, + "recency": 3.2589070053349804e-35, + "frequency": 2.0 + }, + { + "id": "4c301737-73f0-4944-a209-32acae5d4478", + "text": "Caroline says the book taught her self-acceptance, how to find support, that tough times don't last, and that hope and love exist; she also notes that pets bring a lot of joy.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-12T16:33:00+00:00", + "weight": 0.4924063984750212, + "activation": 0.5761958599090576, + "semantic_similarity": 0.5651588016743463, + "recency": 2.9793374365373596e-37, + "frequency": 2.0 + }, + { + "id": "53358350-28d3-4192-ba20-b7259eeebee8", + "text": "Caroline previously struggled with mental health, received helpful support, which made her realize the importance of having a support system for others, and consequently started looking into counseling and mental health career options to assist others on their journeys.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-12T16:33:00+00:00", + "weight": 0.491981419428552, + "activation": 0.5031505271192448, + "semantic_similarity": 0.6367875376425951, + "recency": 2.9793374376615006e-37, + "frequency": 2.0 + }, + { + "id": "006df526-f850-48a9-a2f3-a13799f0391c", + "text": "Melanie states that the conversation with Caroline has been great for her mental health and she intends to continue the positive practices.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-12T16:33:00+00:00", + "weight": 0.4911463040758277, + "activation": 0.5761958599090576, + "semantic_similarity": 0.5609584870103681, + "recency": 2.9793374331028256e-37, + "frequency": 2.0 + }, + { + "id": "ddf46000-7d88-44b4-b9f7-ba012537e710", + "text": "Caroline loves the book \"Becoming Nicole\" by Amy Ellis Nutt, a true story about a trans girl and her family, which made her feel connected, gave her hope for her own path, and she highly recommends it.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-12T16:33:00+00:00", + "weight": 0.4907655327709255, + "activation": 0.5761958599090576, + "semantic_similarity": 0.5596892493273606, + "recency": 2.9793374370442836e-37, + "frequency": 2.0 + }, + { + "id": "5c2765c4-57b3-4606-a52c-53a87daf2b2f", + "text": "Caroline expressed that she is ready to become a mother and share her love and family.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-10-13T10:31:00+00:00", + "weight": 0.4874331455256029, + "activation": 0.4813448124600541, + "semantic_similarity": 0.6434323392919554, + "recency": 3.177903424126703e-33, + "frequency": 2.0 + }, + { + "id": "5e2c78a6-b363-44f7-a74b-23b7b61980f9", + "text": "Caroline has been looking into counseling or mental health work since her last conversation with Melanie, expressing passion for helping people, describing the work as tough but rewarding.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-06T20:18:00+00:00", + "weight": 0.4868065782901396, + "activation": 0.5008205505932704, + "semantic_similarity": 0.6218680437071952, + "recency": 1.6608440540150602e-37, + "frequency": 2.0 + }, + { + "id": "1c925f41-511f-4e75-89ef-b0412f644b60", + "text": "Caroline said the parade motivated her to use her personal story to help others, and she is considering a career in counseling and mental health to give back to the community.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-03T13:36:00+00:00", + "weight": 0.48498031705910283, + "activation": 0.4804768746325535, + "semantic_similarity": 0.6361241822311224, + "recency": 1.1965103429385313e-37, + "frequency": 2.0 + } + ], + "is_correct": true, + "correctness_reasoning": "The predicted answer 'Counseling and mental health' covers the same domains as the correct answer 'Psychology, counseling certification'. 'Counseling' matches the counseling certification, and 'mental health' corresponds to the field of psychology. Thus the content is equivalent." + }, + { + "question": "What is Caroline's identity?", + "correct_answer": "Transgender woman", + "predicted_answer": "Caroline is a trans woman.", + "reasoning": "The context explicitly states that Caroline created a painting intended to represent her journey as a trans woman, indicating her identity.", + "category": 1, + "retrieved_memories": [ + { + "id": "c83ebdb6-822c-4208-8da4-6ffbfdd3fd46", + "text": "Caroline created a painting intended to represent her journey as a trans woman; the red and blue colors symbolize the binary gender system, their mixture signifies breaking that rigidity, and the artwork serves as a reminder to love her authentic self after a long process of self-acceptance.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-09-13T00:09:00+00:00", + "weight": 0.554857861963098, + "activation": 0.674763082010196, + "semantic_similarity": 0.6747631245334641, + "recency": 1.515269859495297e-34, + "frequency": 2.0 + }, + { + "id": "79d809b7-ed0b-48ee-80ed-932bc2b61e87", + "text": "Caroline's artwork focuses on expressing her trans experience, aiming to tell her personal story and help others understand the trans community, as of 2023-08-14.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-14T14:24:00+00:00", + "weight": 0.5542572501175975, + "activation": 0.673762062339537, + "semantic_similarity": 0.6737621047191215, + "recency": 8.005579483282672e-36, + "frequency": 2.0 + }, + { + "id": "1e910def-a7cb-4593-be18-99c833176fa3", + "text": "Caroline's gender transition and artistic expression have altered her relationships: some close friends continue to support her, while a few could not handle the changes; overall she feels happier and her relationships now feel more genuine.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-09-13T00:09:00+00:00", + "weight": 0.5508956355256378, + "activation": 0.668159286003198, + "semantic_similarity": 0.6681594990822615, + "recency": 1.515269859121716e-34, + "frequency": 2.0 + }, + { + "id": "a8b8baac-87de-4f41-b0c5-b32f2870f1d6", + "text": "Caroline is inspired by her work that makes a difference for the LGBTQ+ community, believing that helping create a more loving world is amazing, and this inspiration motivates her to keep making art.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-09-13T00:09:00+00:00", + "weight": 0.5072196185015274, + "activation": 0.5398104656081568, + "semantic_similarity": 0.6509215960636011, + "recency": 1.5152683093644787e-34, + "frequency": 2.0 + }, + { + "id": "ed205e95-5f5f-4fa3-a5de-ae15db6e08ca", + "text": "Caroline has been creating art since she was about 17 years old, finding the practice empowering and cathartic.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-09-13T00:09:00+00:00", + "weight": 0.5054569679485338, + "activation": 0.5398104656081568, + "semantic_similarity": 0.6450460942202894, + "recency": 1.5152683094083203e-34, + "frequency": 2.0 + }, + { + "id": "d4afd073-6eda-41ec-b138-8fc46c23bc23", + "text": "Caroline has not yet tried pottery but is interested in trying new art forms and may try pottery sometime in the future.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-09-13T00:09:00+00:00", + "weight": 0.5008132128945666, + "activation": 0.5398104656081568, + "semantic_similarity": 0.629566910707065, + "recency": 1.5152683098906222e-34, + "frequency": 2.0 + }, + { + "id": "2ddf41e8-b729-4ec4-9371-1c1787bad2b8", + "text": "Caroline creates inclusive and diverse artwork, using it as a platform to advocate for the LGBTQ+ community and promote acceptance; she recently produced a painting (unspecified) as of 2023-08-14.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-14T14:24:00+00:00", + "weight": 0.5006426751759953, + "activation": 0.5390096498716296, + "semantic_similarity": 0.6297992673816878, + "recency": 8.00557129215223e-36, + "frequency": 2.0 + }, + { + "id": "3ac1218b-6a5e-46e7-b7cf-47af5ec87d96", + "text": "Caroline created a self-portrait painting last week (the week of 2023-08-14 to 2023-08-20), which she posted in the conversation.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-16T15:31:00+00:00", + "weight": 0.49407176384397755, + "activation": 0.5390096498716296, + "semantic_similarity": 0.6078962296082956, + "recency": 9.823627847539195e-36, + "frequency": 2.0 + }, + { + "id": "f3826dfa-cd0a-460c-a3d3-b79f67176ce2", + "text": "Caroline is planning to host an LGBTQ art show featuring her paintings in August 2023, specifically scheduled for August 17, 2023.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-17T14:31:00+00:00", + "weight": 0.48931827929138116, + "activation": 0.5390096498716296, + "semantic_similarity": 0.5920512810996408, + "recency": 1.0811645302414841e-35, + "frequency": 2.0 + }, + { + "id": "60fa2ddb-d241-4067-910e-ad8b864ac31b", + "text": "Melanie said that Caroline has always been there for her, and she appreciates their friendship.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-17T13:50:00+00:00", + "weight": 0.48302552657502695, + "activation": 0.5390096498716296, + "semantic_similarity": 0.5710754387117937, + "recency": 1.0780905926085173e-35, + "frequency": 2.0 + }, + { + "id": "88ee8470-c94d-4821-9614-bff8ee8d6433", + "text": "Caroline attended a pride parade on 2023-08-11, describing it as full of energy and love, which made her feel proud and reinforced her belief in the importance of standing up for equality.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-11T14:24:00+00:00", + "weight": 0.4782470974366435, + "activation": 0.5390096498716296, + "semantic_similarity": 0.5551473415838489, + "recency": 5.930673079856595e-36, + "frequency": 2.0 + }, + { + "id": "eab9d6a2-f455-4c10-84e5-fcc6f4c87adc", + "text": "Following her beach visit on August 18, 2023, Caroline painted a sunset scene to capture the calming feeling she experienced.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-18T13:33:00+00:00", + "weight": 0.47668413320904524, + "activation": 0.5390096498716296, + "semantic_similarity": 0.5499374608251877, + "recency": 1.1900685984491014e-35, + "frequency": 2.0 + }, + { + "id": "cd1a7636-f1c8-4f36-bd1b-d7b4bd7ea84b", + "text": "Caroline had a not-so-great experience on a hike where she ran into a group of religious conservatives who said something that upset her, which made her think about how much work still needs to be done for LGBTQ rights.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-17T13:50:00+00:00", + "weight": 0.47655911482930946, + "activation": 0.5390096498716296, + "semantic_similarity": 0.5495207328927352, + "recency": 1.0780905926734e-35, + "frequency": 2.0 + }, + { + "id": "43224c50-a69d-4d79-bda5-98253119a520", + "text": "Caroline expressed appreciation for her friendship with Melanie.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-17T13:50:00+00:00", + "weight": 0.4761944562133029, + "activation": 0.43184837248652547, + "semantic_similarity": 0.6554664815578175, + "recency": 1.0780863881307891e-35, + "frequency": 2.0 + }, + { + "id": "6c731f26-dd5c-4536-b897-8054255fe1b4", + "text": "Caroline produced a painting titled \"Embracing Identity\" that depicts a woman symbolizing the journey of acceptance, with the aim of conveying warmth, love, and self-acceptance; this work was referenced on 2023-08-14.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-14T14:24:00+00:00", + "weight": 0.4761134436611424, + "activation": 0.427593002099958, + "semantic_similarity": 0.6594518101038499, + "recency": 8.005571294663159e-36, + "frequency": 2.0 + }, + { + "id": "45907243-354f-45f5-9bd6-61199272b94e", + "text": "Caroline is organizing an LGBTQ art show scheduled for September 2023 (specifically around September 25, 2023) to exhibit her paintings and promote understanding and acceptance within the community.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-09-25T13:33:00+00:00", + "weight": 0.4745712211164256, + "activation": 0.4494030141151468, + "semantic_similarity": 0.6325010562729384, + "recency": 5.319747596682734e-34, + "frequency": 2.0 + }, + { + "id": "ca9d8d15-1560-4823-936d-79be60dfb4f9", + "text": "Melanie has been involved in art for seven years and has recently identified painting and pottery as her primary muses.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-09-13T00:09:00+00:00", + "weight": 0.47390486518457087, + "activation": 0.5398104656081568, + "semantic_similarity": 0.5398724183404129, + "recency": 1.515268309536357e-34, + "frequency": 2.0 + }, + { + "id": "48495b16-a159-4d5e-bd2b-1db64489b0fb", + "text": "Caroline visited a beach on August 18, 2023, watched the sun set below the horizon, and was inspired by the vivid colors.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-18T13:33:00+00:00", + "weight": 0.4709709878254469, + "activation": 0.5390096498716296, + "semantic_similarity": 0.5308936428798601, + "recency": 1.190068598484887e-35, + "frequency": 2.0 + }, + { + "id": "72855141-35e9-47cd-92aa-5d1ffb89ae3a", + "text": "The LGBTQ support group made Caroline feel accepted and gave her courage to embrace herself.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-05-08T13:56:00+00:00", + "weight": 0.4706860446327654, + "activation": 0.4206203135012283, + "semantic_similarity": 0.6483331686079898, + "recency": 4.430593898215753e-40, + "frequency": 2.0 + }, + { + "id": "50dd73e8-e477-4c45-b052-b3eae96a1a6a", + "text": "Melanie expressed pride in Caroline's work and said she is proud to be part of the difference Caroline is making.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-09T19:55:00+00:00", + "weight": 0.46958491726488694, + "activation": 0.43184837248652547, + "semantic_similarity": 0.6334346850630976, + "recency": 1.1143672569065206e-38, + "frequency": 2.0 + } + ], + "is_correct": true, + "correctness_reasoning": "The predicted answer states that Caroline is a trans woman, which is equivalent to the correct answer 'Transgender woman'." + }, + { + "question": "What did Caroline research?", + "correct_answer": "Adoption agencies", + "predicted_answer": "Caroline researched career options in counseling and mental health, as well as adoption agencies.", + "reasoning": "The context explicitly states that Caroline is researching a career in counseling and mental health (items 0, 1, 6, 12, 16) and also mentions her research into adoption agencies (item 2). Therefore, both areas of research are clearly indicated in the provided context.", + "category": 1, + "retrieved_memories": [ + { + "id": "eeb4a464-dc3f-4123-a16e-bfa95dedf0ea", + "text": "Caroline has recently been researching a career in counseling and mental health because she wants to help people who have experienced similar challenges to her own.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-27T10:37:00+00:00", + "weight": 0.5794384677544774, + "activation": 0.715730743662682, + "semantic_similarity": 0.7157308155189092, + "recency": 6.485732412751227e-38, + "frequency": 2.0 + }, + { + "id": "c759737b-8fff-4941-8c74-c832339e7595", + "text": "Caroline is actively researching and considering career options in counseling and mental health because she believes it is important for people to have someone to talk to and wants to help make that happen.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-12T16:33:00+00:00", + "weight": 0.5696282642038295, + "activation": 0.699380439482955, + "semantic_similarity": 0.6993804411964767, + "recency": 2.9794594154744854e-37, + "frequency": 2.0 + }, + { + "id": "0188d9d9-2ecb-4339-b41f-071e91baba40", + "text": "Caroline is researching adoption agencies because she has long dreamed of having a family and giving a loving home to children who need one.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-05-25T13:14:00+00:00", + "weight": 0.5632356338407093, + "activation": 0.688726092013202, + "semantic_similarity": 0.6887260207891623, + "recency": 2.4183672474861377e-39, + "frequency": 2.0 + }, + { + "id": "bf146ef5-5001-4773-af33-8ab30c2b167f", + "text": "Caroline plans to specialize in working with transgender individuals, aiming to help them accept themselves and support their mental health.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-27T10:37:00+00:00", + "weight": 0.5072137320716724, + "activation": 0.5725845949301456, + "semantic_similarity": 0.6181278453087624, + "recency": 6.485724067976057e-38, + "frequency": 2.0 + }, + { + "id": "1a905e0b-4767-4a9e-b3ad-bc32d0657ab2", + "text": "Caroline says that her own personal journey and the support she received significantly improved her life; observing the benefits of counseling and support groups motivated her to care more about mental health, understand herself better, and create a safe, inviting environment for others to grow.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-27T10:37:00+00:00", + "weight": 0.5017927726791095, + "activation": 0.5725845949301456, + "semantic_similarity": 0.6000579806668861, + "recency": 6.485724067765822e-38, + "frequency": 2.0 + }, + { + "id": "83e62a1b-74b9-40e2-b6d8-e4d9dab557a6", + "text": "Caroline received a necklace as a gift from her grandmother in Sweden when she was young; the necklace symbolizes love, faith, and strength and serves as a reminder of her roots and the love and support she receives from her family.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-27T10:37:00+00:00", + "weight": 0.5008315705800984, + "activation": 0.5725845949301456, + "semantic_similarity": 0.5968539736701824, + "recency": 6.485724068959394e-38, + "frequency": 2.0 + }, + { + "id": "280b9bd7-1ed9-4a8a-b169-89af4775ae9b", + "text": "Caroline is keen on becoming a counselor or working in mental health so she can support people who face similar issues.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-05-08T13:56:00+00:00", + "weight": 0.4992268594298619, + "activation": 0.5340787715851291, + "semantic_similarity": 0.630010759847744, + "recency": 4.430857334771276e-40, + "frequency": 2.0 + }, + { + "id": "73850c77-935b-45c3-9a68-3552e0f85121", + "text": "Caroline emphasizes that mental health is a priority and advises Melanie to take care of herself.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-12T16:33:00+00:00", + "weight": 0.49883968642847987, + "activation": 0.559504351586364, + "semantic_similarity": 0.6032946031752354, + "recency": 2.9794555800195424e-37, + "frequency": 2.0 + }, + { + "id": "a10ae2d0-45de-4fbb-8c37-9762142b5158", + "text": "As of July 17, 2023, Caroline is mentoring a transgender teen who shares her own gender identity, and together they are working on building confidence and developing positive coping strategies.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-17T14:31:00+00:00", + "weight": 0.49703533128847976, + "activation": 0.559504351586364, + "semantic_similarity": 0.5972800860419019, + "recency": 4.87084956709961e-37, + "frequency": 2.0 + }, + { + "id": "a4f20608-0fb6-4235-b47b-b64482d3e648", + "text": "Caroline stated her goal is to give kids a loving home, expressed gratitude for support from friends and mentors, and said she feels hopeful and optimistic about turning her adoption dream into reality.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-05-25T13:14:00+00:00", + "weight": 0.49699247986583384, + "activation": 0.5509808736105616, + "semantic_similarity": 0.6056607259422179, + "recency": 2.4183641336192322e-39, + "frequency": 2.0 + }, + { + "id": "05f1dcaa-6f99-46b5-87e9-d2efa64e01cd", + "text": "Caroline joined a mentorship program for LGBTQ youth on the weekend of July 15\u201316, 2023, aiming to support and empower young members of the community.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-15T14:31:00+00:00", + "weight": 0.494513164550792, + "activation": 0.559504351586364, + "semantic_similarity": 0.5888728635829426, + "recency": 3.9879143305085155e-37, + "frequency": 2.0 + }, + { + "id": "d8b3fb45-7e02-4aad-8cd9-79e0a7cc1a76", + "text": "Caroline chose a specific adoption agency because it assists LGBTQ+ individuals with adoption, and she was attracted to its inclusivity and support.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-05-25T13:14:00+00:00", + "weight": 0.4941924669756822, + "activation": 0.5509808736105616, + "semantic_similarity": 0.5963273496417124, + "recency": 2.41836413352407e-39, + "frequency": 2.0 + }, + { + "id": "53358350-28d3-4192-ba20-b7259eeebee8", + "text": "Caroline previously struggled with mental health, received helpful support, which made her realize the importance of having a support system for others, and consequently started looking into counseling and mental health career options to assist others on their journeys.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-12T16:33:00+00:00", + "weight": 0.4939609162862364, + "activation": 0.4934357091231964, + "semantic_similarity": 0.6531006784975917, + "recency": 2.9794555825023955e-37, + "frequency": 2.0 + }, + { + "id": "60b8d54d-4c1f-477b-904e-38ab8949bf06", + "text": "Caroline expressed excitement about creating a family for children in need, acknowledged that it will be challenging as a single parent, but affirmed she is ready for the challenge.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-05-25T13:14:00+00:00", + "weight": 0.49364870295561747, + "activation": 0.5509808736105616, + "semantic_similarity": 0.5945148029081634, + "recency": 2.41836413346245e-39, + "frequency": 2.0 + }, + { + "id": "006df526-f850-48a9-a2f3-a13799f0391c", + "text": "Melanie states that the conversation with Caroline has been great for her mental health and she intends to continue the positive practices.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-12T16:33:00+00:00", + "weight": 0.48826275503183203, + "activation": 0.559504351586364, + "semantic_similarity": 0.5680381651864093, + "recency": 2.979455580557522e-37, + "frequency": 2.0 + }, + { + "id": "ddf46000-7d88-44b4-b9f7-ba012537e710", + "text": "Caroline loves the book \"Becoming Nicole\" by Amy Ellis Nutt, a true story about a trans girl and her family, which made her feel connected, gave her hope for her own path, and she highly recommends it.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-12T16:33:00+00:00", + "weight": 0.48645685184642806, + "activation": 0.559504351586364, + "semantic_similarity": 0.5620184879017295, + "recency": 2.9794555818471747e-37, + "frequency": 2.0 + }, + { + "id": "5e2c78a6-b363-44f7-a74b-23b7b61980f9", + "text": "Caroline has been looking into counseling or mental health work since her last conversation with Melanie, expressing passion for helping people, describing the work as tough but rewarding.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-06T20:18:00+00:00", + "weight": 0.48609639250226766, + "activation": 0.49115071972664925, + "semantic_similarity": 0.629170588614243, + "recency": 1.6609099143444882e-37, + "frequency": 2.0 + }, + { + "id": "55aa9ea8-0635-4680-9ed1-243b08e8d5fc", + "text": "Caroline's goal is to have a family; she hopes to build her own family by adopting children and providing them a home, viewing adoption as a way of giving back and showing love and acceptance.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-10-22T09:55:00+00:00", + "weight": 0.485850455679414, + "activation": 0.48001741392383207, + "semantic_similarity": 0.6394841050075479, + "recency": 7.797173772342497e-33, + "frequency": 2.0 + }, + { + "id": "5819027e-8dda-4d6c-aecf-696e998337c2", + "text": "Caroline plans to continue her education and explore career options, expressing excitement about the prospect.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-05-08T13:56:00+00:00", + "weight": 0.48272074488201033, + "activation": 0.4272630172681033, + "semantic_similarity": 0.6818061323385977, + "recency": 4.4308439583049156e-40, + "frequency": 2.0 + }, + { + "id": "4c301737-73f0-4944-a209-32acae5d4478", + "text": "Caroline says the book taught her self-acceptance, how to find support, that tough times don't last, and that hope and love exist; she also notes that pets bring a lot of joy.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-12T16:33:00+00:00", + "weight": 0.48229796156010274, + "activation": 0.559504351586364, + "semantic_similarity": 0.5481555202806452, + "recency": 2.9794555817644835e-37, + "frequency": 2.0 + } + ], + "is_correct": true, + "correctness_reasoning": "The predicted answer includes \"adoption agencies,\" which matches the correct answer. Although it adds extra information about career options in counseling and mental health, it still contains the required answer, so it is considered equivalent." + }, + { + "question": "When did Caroline meet up with her friends, family, and mentors?", + "correct_answer": "The week before 9 June 2023", + "predicted_answer": "I don't know", + "reasoning": "The context does not provide specific dates or instances of Caroline meeting up with her friends, family, and mentors. It mentions her gratitude for their support and her experiences with them, but it does not specify when these meetings occurred.", + "category": 2, + "retrieved_memories": [ + { + "id": "0b5694e4-7c0b-422c-bed4-588d92fb067f", + "text": "Caroline has known her current friends for four years, having moved from her home country around 2019-06-09.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-09T19:55:00+00:00", + "weight": 0.6010526862460175, + "activation": 0.751754485122993, + "semantic_similarity": 0.7517544690303984, + "recency": 1.1144318304372272e-38, + "frequency": 2.0 + }, + { + "id": "d8fcc8ca-5510-49a0-bab6-667aabb04d42", + "text": "Caroline contacted her mentor for adoption advice.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-10-13T10:31:00+00:00", + "weight": 0.5908183021046474, + "activation": 0.734697185000694, + "semantic_similarity": 0.7346971553481304, + "recency": 3.178001608290096e-33, + "frequency": 2.0 + }, + { + "id": "5f5ec14c-8715-4770-988a-6aa1fe4176f0", + "text": "Caroline attended an LGBTQ support group on 2023-05-07, finding the experience powerful.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-05-07T13:56:00+00:00", + "weight": 0.5846830075977348, + "activation": 0.724471688270569, + "semantic_similarity": 0.7244716703885473, + "recency": 4.009170396332213e-40, + "frequency": 2.0 + }, + { + "id": "ad619ec1-c081-4fab-bb8f-707d8eed6fc0", + "text": "Caroline mentioned a tough breakup in the past and expressed thankfulness for her friends, family, and mentors who have supported her.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-09T19:55:00+00:00", + "weight": 0.5438181993793406, + "activation": 0.6014035880983944, + "semantic_similarity": 0.7113237431660742, + "recency": 1.1144300572150759e-38, + "frequency": 2.0 + }, + { + "id": "ec88eee3-ba37-427f-9bf4-e0995d5fc61a", + "text": "On Friday, June 23, 2023, Caroline attended an LGBTQ+ counseling workshop where professionals discussed various therapeutic methods for working with transgender people and demonstrated passion for creating safe spaces for individuals like her.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-23T10:37:00+00:00", + "weight": 0.5317243625786355, + "activation": 0.5795773506164552, + "semantic_similarity": 0.6928371913123298, + "recency": 4.3474658545707335e-38, + "frequency": 2.0 + }, + { + "id": "c5161f91-693c-48a1-a288-ad149f8fc765", + "text": "Caroline attended an LGBTQ conference on 2023-07-10, two days before the reference date, where she met and connected with people who have experienced similar journeys, found the environment welcoming, felt totally accepted, and expressed gratitude for the community.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-10T16:33:00+00:00", + "weight": 0.5304923054101583, + "activation": 0.5795773506164552, + "semantic_similarity": 0.6887303340840725, + "recency": 2.439346662855671e-37, + "frequency": 2.0 + }, + { + "id": "5c2765c4-57b3-4606-a52c-53a87daf2b2f", + "text": "Caroline expressed that she is ready to become a mother and share her love and family.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-10-13T10:31:00+00:00", + "weight": 0.5223467720549109, + "activation": 0.5877577480005552, + "semantic_similarity": 0.6533981588491475, + "recency": 3.1779965507657496e-33, + "frequency": 2.0 + }, + { + "id": "3f797cf0-1c31-4f25-8815-0791293e3bcd", + "text": "During her transition and journey toward self-acceptance, Caroline received invaluable help and encouragement from friends, family, and people she looked up to, which boosted her through tough times and helped her discover her true self.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-10-22T09:55:00+00:00", + "weight": 0.5159861957616187, + "activation": 0.5795773506164552, + "semantic_similarity": 0.6403766352556072, + "recency": 7.797093076866785e-33, + "frequency": 2.0 + }, + { + "id": "05f1dcaa-6f99-46b5-87e9-d2efa64e01cd", + "text": "Caroline joined a mentorship program for LGBTQ youth on the weekend of July 15\u201316, 2023, aiming to support and empower young members of the community.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-15T14:31:00+00:00", + "weight": 0.5112932706091949, + "activation": 0.4996917704239485, + "semantic_similarity": 0.7046191316067013, + "recency": 3.987873055010309e-37, + "frequency": 2.0 + }, + { + "id": "aa36595e-58ca-42dc-b50d-8c785526bbf3", + "text": "Melanie's support has been meaningful to Caroline; Caroline feels grateful for Melanie's support throughout her journey and values being able to share and help others.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-10-22T09:55:00+00:00", + "weight": 0.5109544632213276, + "activation": 0.5795773506164552, + "semantic_similarity": 0.6236041934546369, + "recency": 7.797093076623018e-33, + "frequency": 2.0 + }, + { + "id": "88e28f0b-51b1-45bb-860b-4b1a734d3462", + "text": "Caroline reflected that volunteering reminded her of her own past struggles and feeling alone, and she was glad to share her story and offer support, feeling she could make a difference.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-28T15:19:00+00:00", + "weight": 0.5108315798564431, + "activation": 0.5795773506164552, + "semantic_similarity": 0.6231945822383552, + "recency": 3.2590025028256203e-35, + "frequency": 2.0 + }, + { + "id": "a4f20608-0fb6-4235-b47b-b64482d3e648", + "text": "Caroline stated her goal is to give kids a loving home, expressed gratitude for support from friends and mentors, and said she feels hopeful and optimistic about turning her adoption dream into reality.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-05-25T13:14:00+00:00", + "weight": 0.5103946960187441, + "activation": 0.5795773506164552, + "semantic_similarity": 0.6217383027793583, + "recency": 2.418339104239752e-39, + "frequency": 2.0 + }, + { + "id": "63dd0bce-9e94-439c-a66b-2348579d05dc", + "text": "Caroline attended an LGBTQ+ pride parade, observed a happy crowd, felt a sense of belonging, and recognized significant growth in the LGBTQ+ community.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-26T13:36:00+00:00", + "weight": 0.5084066605467776, + "activation": 0.5795773506164552, + "semantic_similarity": 0.6151115178728037, + "recency": 5.941868633581348e-38, + "frequency": 2.0 + }, + { + "id": "43224c50-a69d-4d79-bda5-98253119a520", + "text": "Caroline expressed appreciation for her friendship with Melanie.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-08-17T13:50:00+00:00", + "weight": 0.5072750954977371, + "activation": 0.4811228704787156, + "semantic_similarity": 0.7097941145137414, + "recency": 1.0781391322707423e-35, + "frequency": 2.0 + }, + { + "id": "c7ffecc3-a614-401d-9f62-a23753c7ca5f", + "text": "Melanie has been reading a book that Caroline recommended a while ago and has been painting to keep busy.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-10-13T10:31:00+00:00", + "weight": 0.5060902901101197, + "activation": 0.5877577480005552, + "semantic_similarity": 0.5992098856998439, + "recency": 3.177996550684864e-33, + "frequency": 2.0 + }, + { + "id": "453f811d-9535-42e7-8784-7a0eb35362ba", + "text": "During the June 17, 2023 LGBT pride event, Caroline recalls that the best moment was seeing her mentee's face light up upon witnessing the community's support.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-17T14:31:00+00:00", + "weight": 0.5060437535470546, + "activation": 0.5795773506164552, + "semantic_similarity": 0.6072351612070598, + "recency": 2.4250281037657853e-38, + "frequency": 2.0 + }, + { + "id": "1a905e0b-4767-4a9e-b3ad-bc32d0657ab2", + "text": "Caroline says that her own personal journey and the support she received significantly improved her life; observing the benefits of counseling and support groups motivated her to care more about mental health, understand herself better, and create a safe, inviting environment for others to grow.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-27T10:37:00+00:00", + "weight": 0.5058604333261678, + "activation": 0.5795773506164552, + "semantic_similarity": 0.6066240938041042, + "recency": 6.485656933843071e-38, + "frequency": 2.0 + }, + { + "id": "98c08619-7bb3-467c-a87e-027ee4b31021", + "text": "Both Caroline and Melanie affirmed their commitment to continue supporting each other, spreading love, acceptance, and hope, and to motivate each other through life's challenges.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-09T19:55:00+00:00", + "weight": 0.50464851264145, + "activation": 0.6014035880983944, + "semantic_similarity": 0.5807581207064392, + "recency": 1.1144300571454247e-38, + "frequency": 2.0 + }, + { + "id": "d20a1038-61b6-4baa-9d6a-7d3a729434af", + "text": "Caroline expressed gratitude for the love and support she has received throughout her transition and aims to give a voice to the trans community.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-06-09T19:55:00+00:00", + "weight": 0.5045089567986043, + "activation": 0.6014035880983944, + "semantic_similarity": 0.5802929345636201, + "recency": 1.1144300571764019e-38, + "frequency": 2.0 + }, + { + "id": "3a2f0dfc-4fc1-4986-9474-ce54481550a3", + "text": "Caroline joined a new LGBTQ activist group called Connected LGBTQ Activists on Tuesday, July 18, 2023.", + "context": "Conversation session between Caroline and Melanie", + "event_date": "2023-07-18T20:56:00+00:00", + "weight": 0.5030478276643547, + "activation": 0.48810711378264965, + "semantic_similarity": 0.6887189784318661, + "recency": 5.528929027864583e-37, + "frequency": 2.0 + } + ], + "is_correct": false, + "correctness_reasoning": "The predicted answer 'I don't know' does not provide the information that Caroline met up with her friends, family, and mentors the week before 9 June 2023, so it is not equivalent to the correct answer." } ] }, - "total_turns": 419 + "total_turns": -1 } ] } \ No newline at end of file diff --git a/benchmarks/locomo/run_benchmark.py b/benchmarks/locomo/run_benchmark.py index 2a4d2f9c..f883b971 100644 --- a/benchmarks/locomo/run_benchmark.py +++ b/benchmarks/locomo/run_benchmark.py @@ -13,10 +13,12 @@ import json from datetime import datetime, timezone, timedelta from memory import TemporalSemanticMemory from typing import List, Dict +from openai import AsyncOpenAI import openai from dotenv import load_dotenv import os import asyncio +import pydantic from rich.console import Console from rich.progress import Progress, SpinnerColumn, TextColumn, BarColumn from rich.table import Table @@ -27,6 +29,24 @@ load_dotenv() console = Console() +def get_groq_client() -> AsyncOpenAI: + """ + Get configured async Groq client for LLM judge. + + Returns: + Configured AsyncOpenAI client pointing to Groq + """ + groq_api_key = os.getenv('GROQ_API_KEY') + if not groq_api_key: + raise ValueError("GROQ_API_KEY environment variable not set") + + base_url = os.getenv('GROQ_BASE_URL', 'https://api.groq.com/openai/v1') + return AsyncOpenAI( + api_key=groq_api_key, + base_url=base_url + ) + + def parse_date(date_string: str) -> datetime: """Parse LoComo date format to datetime.""" # Format: "1:56 pm on 8 May, 2023" @@ -41,7 +61,7 @@ async def ingest_conversation(memory: TemporalSemanticMemory, conversation_data: """ Ingest a LoComo conversation into the memory system (ASYNC version). - Ingests entire conversation as a single large document for maximum efficiency. + Ingests ALL sessions in ONE batch for maximum efficiency. Args: memory: Memory system instance @@ -55,45 +75,55 @@ async def ingest_conversation(memory: TemporalSemanticMemory, conversation_data: # Get all session keys sorted session_keys = sorted([k for k in conv.keys() if k.startswith('session_') and not k.endswith('_date_time')]) + # Collect all sessions as batch items + batch_contents = [] total_turns = 0 - # Build entire conversation as one large text - conversation_parts = [] - for session_key in session_keys: if session_key not in conv or not isinstance(conv[session_key], list): continue session_data = conv[session_key] - # Add all turns from this session + # Build session content from all turns + session_parts = [] for turn in session_data: speaker = turn['speaker'] text = turn['text'] - conversation_parts.append(f"{speaker} said: {text}") + session_parts.append(f"{speaker}: {text}") total_turns += 1 - # Ingest entire conversation in ONE put_async call - # Use the first session date as the event date - first_session_key = session_keys[0] if session_keys else "session_1" - date_key = f"{first_session_key}_date_time" - conversation_date = parse_date(conv.get(date_key, "1:00 pm on 1 January, 2023")) + if not session_parts: + continue - full_conversation = " ".join(conversation_parts) + # Get session date + date_key = f"{session_key}_date_time" + session_date = parse_date(conv.get(date_key, "1:00 pm on 1 January, 2023")) - await memory.put_async( - agent_id=agent_id, - content=full_conversation, - context=f"Full conversation between {speaker_a} and {speaker_b}", - event_date=conversation_date - ) + # Add to batch + session_content = "\n".join(session_parts) + batch_contents.append({ + "content": session_content, + "context": f"Conversation session between {speaker_a} and {speaker_b}", + "event_date": session_date + }) + + # Ingest ALL sessions in ONE batch call (MUCH faster!) + if batch_contents: + await memory.put_batch_async( + agent_id=agent_id, + contents=batch_contents + ) return total_turns +class QuestionAnswer(pydantic.BaseModel): + answer: str + reasoning: str -def answer_question(memory: TemporalSemanticMemory, agent_id: str, question: str, thinking_budget: int = 100) -> str: +async def answer_question(memory: TemporalSemanticMemory, agent_id: str, question: str, thinking_budget: int = 500) -> tuple[str, str, List[Dict]]: """ - Answer a question using the memory system. + Answer a question using the memory system (ASYNC version). Args: memory: Memory system instance @@ -102,36 +132,33 @@ def answer_question(memory: TemporalSemanticMemory, agent_id: str, question: str thinking_budget: How many memory units to explore Returns: - Answer string + Tuple of (answer string, reasoning string, retrieved memories list) """ # Search memory - results = memory.search( + results = await memory.search_async( agent_id=agent_id, query=question, thinking_budget=thinking_budget, top_k=20 # Get more results for better context ) - print("question:", question) - print("Got results:", results) - if not results: - return "I don't have enough information to answer that question." + return "I don't have enough information to answer that question.", "No relevant memories found.", [] - # Build context from top results context_parts = [] - for i, result in enumerate(results[:10], 1): + for i, result in enumerate(results): context_parts.append(f"{i}. {result['text']}") context = "\n".join(context_parts) - # Use OpenAI to generate answer from context + # Use AsyncOpenAI to generate answer from context try: - response = openai.chat.completions.create( + client = AsyncOpenAI() + response = await client.beta.chat.completions.parse( model="gpt-4o-mini", messages=[ { "role": "system", - "content": "You are a helpful assistant. Answer the question based ONLY on the provided context. If the context doesn't contain the answer, say 'I don't know'." + "content": "You are a helpful assistant. Answer the question based ONLY on the provided context. If the context doesn't contain the answer, say 'I don't know'. In the reasoning, explain why you choose or not choose the context items for the answer." }, { "role": "user", @@ -139,14 +166,16 @@ def answer_question(memory: TemporalSemanticMemory, agent_id: str, question: str } ], temperature=0, - max_tokens=150 + max_tokens=8000, + response_format=QuestionAnswer ) - return response.choices[0].message.content.strip() + answer = response.choices[0].message.parsed + return answer.answer, answer.reasoning, results except Exception as e: - return f"Error generating answer: {str(e)}" + return f"Error generating answer: {str(e)}", "Error occurred during answer generation.", results -def evaluate_qa_task( +async def evaluate_qa_task( memory: TemporalSemanticMemory, agent_id: str, qa_pairs: List[Dict], @@ -154,13 +183,11 @@ def evaluate_qa_task( max_questions: int = None ) -> Dict: """ - Evaluate the QA task. + Evaluate the QA task (ASYNC version - processes questions in parallel). Returns: Dict with evaluation metrics """ - results = [] - questions_to_eval = qa_pairs[:max_questions] if max_questions else qa_pairs with Progress( @@ -170,38 +197,97 @@ def evaluate_qa_task( TextColumn("[progress.percentage]{task.percentage:>3.0f}%"), console=console ) as progress: - task = progress.add_task(f"[cyan]Evaluating QA for sample {sample_id}...", total=len(questions_to_eval)) + task = progress.add_task(f"[cyan]Evaluating QA for sample {sample_id} (parallel)...", total=len(questions_to_eval)) - for qa in questions_to_eval: + # Create tasks for all questions + async def process_question(qa): question = qa['question'] correct_answer = qa['answer'] category = qa.get('category', 0) - # Get predicted answer - predicted_answer = answer_question(memory, agent_id, question) + # Get predicted answer, reasoning, and retrieved memories + predicted_answer, reasoning, retrieved_memories = await answer_question(memory, agent_id, question) - results.append({ + return { 'question': question, 'correct_answer': correct_answer, 'predicted_answer': predicted_answer, - 'category': category - }) + 'reasoning': reasoning, + 'category': category, + 'retrieved_memories': retrieved_memories + } + # Process all questions in parallel + question_tasks = [process_question(qa) for qa in questions_to_eval] + + # Use as_completed to update progress as results come in + results = [] + for coro in asyncio.as_completed(question_tasks): + result = await coro + results.append(result) progress.update(task, advance=1) return results +class JudgeResponse(pydantic.BaseModel): + correct: bool + reasoning: str -def calculate_metrics(results: List[Dict]) -> Dict: +async def judge_single_answer(client: AsyncOpenAI, result: Dict, semaphore: asyncio.Semaphore) -> Dict: """ - Calculate evaluation metrics. + Judge a single answer using LLM (with concurrency control). - Uses LLM-as-judge to evaluate answer quality. + Args: + client: Async OpenAI client (Groq) + result: Result dict with question, correct_answer, predicted_answer, category + semaphore: Semaphore to limit concurrent requests + + Returns: + Updated result dict with is_correct field + """ + async with semaphore: + try: + response = await client.beta.chat.completions.parse( + model="openai/gpt-oss-120b", + messages=[ + { + "role": "system", + "content": + "You are an objective judge. Determine if the predicted answer contains the correct answer or they are the same content (with different form is fine)." + }, + { + "role": "user", + "content": f"Question: {result['question']}\nCorrect answer: {result['correct_answer']}\nPredicted answer: {result['predicted_answer']}\n\nAre they equivalent?" + } + ], + temperature=0, + max_tokens=512, + response_format=JudgeResponse + + ) + + judgement = response.choices[0].message.parsed + result['is_correct'] = judgement.correct + result['correctness_reasoning'] = judgement.reasoning + + except Exception as e: + console.print(f"[red]Error judging answer: {e}[/red]") + result['is_correct'] = False + + return result + + +async def calculate_metrics(results: List[Dict]) -> Dict: + """ + Calculate evaluation metrics using parallel LLM-as-judge. + + Processes up to 8 judgments concurrently for speed. """ - correct = 0 total = len(results) + client = get_groq_client() - category_stats = {} + # Semaphore to limit to 8 concurrent requests + semaphore = asyncio.Semaphore(8) with Progress( SpinnerColumn(), @@ -210,49 +296,33 @@ def calculate_metrics(results: List[Dict]) -> Dict: TextColumn("[progress.percentage]{task.percentage:>3.0f}%"), console=console ) as progress: - task = progress.add_task("[yellow]Judging answers with LLM...", total=total) + task = progress.add_task("[yellow]Judging answers with LLM (parallel, max 8)...", total=total) + # Create all judgment tasks + judgment_tasks = [] for result in results: - # Use LLM as judge - try: - response = openai.chat.completions.create( - model="gpt-4o-mini", - messages=[ - { - "role": "system", - "content": "You are an objective judge. Determine if the predicted answer is semantically equivalent to the correct answer. Answer with ONLY 'yes' or 'no'." - }, - { - "role": "user", - "content": f"Question: {result['question']}\nCorrect answer: {result['correct_answer']}\nPredicted answer: {result['predicted_answer']}\n\nAre they equivalent?" - } - ], - temperature=0, - max_tokens=5 - ) - - judgment = response.choices[0].message.content.strip().lower() - is_correct = 'yes' in judgment - - if is_correct: - correct += 1 - - result['is_correct'] = is_correct - - # Track by category - category = result['category'] - if category not in category_stats: - category_stats[category] = {'correct': 0, 'total': 0} - category_stats[category]['total'] += 1 - if is_correct: - category_stats[category]['correct'] += 1 - - except Exception as e: - console.print(f"[red]Error judging answer: {e}[/red]") - result['is_correct'] = False + judgment_task = judge_single_answer(client, result, semaphore) + judgment_tasks.append(judgment_task) + # Process in parallel with progress updates + judged_results = [] + for coro in asyncio.as_completed(judgment_tasks): + judged_result = await coro + judged_results.append(judged_result) progress.update(task, advance=1) + # Calculate stats + correct = sum(1 for r in judged_results if r.get('is_correct', False)) + category_stats = {} + + for result in judged_results: + category = result['category'] + if category not in category_stats: + category_stats[category] = {'correct': 0, 'total': 0} + category_stats[category]['total'] += 1 + if result.get('is_correct', False): + category_stats[category]['correct'] += 1 + accuracy = (correct / total * 100) if total > 0 else 0 return { @@ -260,17 +330,82 @@ def calculate_metrics(results: List[Dict]) -> Dict: 'correct': correct, 'total': total, 'category_stats': category_stats, - 'detailed_results': results + 'detailed_results': judged_results } -def run_benchmark(max_conversations: int = None, max_questions_per_conv: int = None): +async def process_single_conversation( + memory: TemporalSemanticMemory, + conv_data: Dict, + i: int, + total_convs: int, + max_questions_per_conv: int, + skip_ingestion: bool +) -> Dict: + """ + Process a single conversation (ingest + evaluate). + + Args: + memory: Memory system instance + conv_data: Conversation data + i: Conversation index (1-based) + total_convs: Total number of conversations + max_questions_per_conv: Max questions to evaluate per conversation + skip_ingestion: Whether to skip ingestion + + Returns: + Result dict with sample_id, metrics, total_turns + """ + sample_id = conv_data['sample_id'] + agent_id = "locomo" # Single agent for all Locomo benchmark data + + console.print(f"\n[bold blue]Conversation {i}/{total_convs}[/bold blue] (Sample ID: {sample_id})") + + if not skip_ingestion: + # Clear previous locomo agent data only (multi-tenant safe) + if i == 1: # Only cleanup on first conversation + console.print(" [2] Clearing previous 'locomo' agent data...") + memory.delete_agent(agent_id) + console.print(f" [green]✓[/green] Cleared 'locomo' agent data") + + # Ingest conversation (sessions processed in parallel) + console.print(" [3] Ingesting conversation (sessions in parallel)...") + total_turns = await ingest_conversation(memory, conv_data, agent_id) + console.print(f" [green]✓[/green] Ingested {total_turns} turns across multiple sessions") + else: + total_turns = -1 + + # Evaluate QA (async - questions processed in parallel) + console.print(f" [4] Evaluating {len(conv_data['qa'])} QA pairs (parallel)...") + qa_results = await evaluate_qa_task( + memory, + agent_id, + conv_data['qa'], + sample_id, + max_questions=max_questions_per_conv + ) + + # Calculate metrics (async with parallel LLM judging) + console.print(" [5] Calculating metrics...") + metrics = await calculate_metrics(qa_results) + + console.print(f" [green]✓[/green] Accuracy: {metrics['accuracy']:.2f}% ({metrics['correct']}/{metrics['total']})") + + return { + 'sample_id': sample_id, + 'metrics': metrics, + 'total_turns': total_turns + } + + +def run_benchmark(max_conversations: int = None, max_questions_per_conv: int = None, skip_ingestion: bool = False): """ Run the LoComo benchmark. Args: max_conversations: Maximum number of conversations to evaluate (None for all) max_questions_per_conv: Maximum questions per conversation (None for all) + skip_ingestion: Whether to skip ingestion and use existing data """ console.print("\n[bold cyan]LoComo Benchmark - Entity-Aware Memory System[/bold cyan]") console.print("=" * 80) @@ -288,54 +423,17 @@ def run_benchmark(max_conversations: int = None, max_questions_per_conv: int = N memory = TemporalSemanticMemory() console.print(" [green]✓[/green] Memory system initialized") - # Run evaluation for each conversation + # Run evaluation (conversations sequential, sessions within each conversation parallel) all_results = [] for i, conv_data in enumerate(conversations_to_eval, 1): - sample_id = conv_data['sample_id'] - agent_id = f"locomo_{sample_id}" - - console.print(f"\n[bold blue]Conversation {i}/{len(conversations_to_eval)}[/bold blue] (Sample ID: {sample_id})") - - # Clear previous data - import psycopg2 - conn = psycopg2.connect(os.getenv('DATABASE_URL')) - cursor = conn.cursor() - cursor.execute("DELETE FROM memory_units WHERE agent_id = %s", (agent_id,)) - cursor.execute("DELETE FROM memory_links WHERE agent_id = %s", (agent_id,)) - cursor.execute("DELETE FROM entity_cooccurrences WHERE agent_id = %s", (agent_id,)) - cursor.execute("DELETE FROM unit_entities WHERE agent_id = %s", (agent_id,)) - cursor.execute("DELETE FROM entities WHERE agent_id = %s", (agent_id,)) - conn.commit() - cursor.close() - conn.close() - - # Ingest conversation (using async for parallel embedding generation) - console.print(" [3] Ingesting conversation (async with parallel embeddings)...") - total_turns = asyncio.run(ingest_conversation(memory, conv_data, agent_id)) - console.print(f" [green]✓[/green] Ingested {total_turns} conversation turns") - - # Evaluate QA - console.print(f" [4] Evaluating {len(conv_data['qa'])} QA pairs...") - qa_results = evaluate_qa_task( - memory, - agent_id, - conv_data['qa'], - sample_id, - max_questions=max_questions_per_conv + result = asyncio.run( + process_single_conversation( + memory, conv_data, i, len(conversations_to_eval), + max_questions_per_conv, skip_ingestion + ) ) - - # Calculate metrics - console.print(" [5] Calculating metrics...") - metrics = calculate_metrics(qa_results) - - console.print(f" [green]✓[/green] Accuracy: {metrics['accuracy']:.2f}% ({metrics['correct']}/{metrics['total']})") - - all_results.append({ - 'sample_id': sample_id, - 'metrics': metrics, - 'total_turns': total_turns - }) + all_results.append(result) # Overall results console.print("\n[bold green]✓ Benchmark Complete![/bold green]\n") @@ -387,12 +485,14 @@ if __name__ == "__main__": parser = argparse.ArgumentParser(description='Run LoComo benchmark') parser.add_argument('--max-conversations', type=int, default=None, help='Maximum conversations to evaluate') parser.add_argument('--max-questions', type=int, default=None, help='Maximum questions per conversation') + parser.add_argument('--skip-ingestion', action='store_true', help='Skip ingestion and use existing data') args = parser.parse_args() results = run_benchmark( max_conversations=args.max_conversations, - max_questions_per_conv=args.max_questions + max_questions_per_conv=args.max_questions, + skip_ingestion=args.skip_ingestion ) # Save results diff --git a/benchmarks/longmemeval/run_benchmark.py b/benchmarks/longmemeval/run_benchmark.py index e27adef6..72173e16 100644 --- a/benchmarks/longmemeval/run_benchmark.py +++ b/benchmarks/longmemeval/run_benchmark.py @@ -22,6 +22,7 @@ from typing import Dict, List, Any from pathlib import Path import time import asyncio +import subprocess from dotenv import load_dotenv # Load environment variables from .env @@ -74,6 +75,43 @@ def parse_args(): return parser.parse_args() +def download_dataset(dataset_path: Path) -> bool: + """ + Download the LongMemEval dataset if it doesn't exist. + + Returns: + True if successful, False otherwise + """ + url = "https://huggingface.co/datasets/xiaowu0162/longmemeval-cleaned/resolve/main/longmemeval_s_cleaned.json" + + console.print(f"[yellow]Dataset not found. Downloading from HuggingFace...[/yellow]") + console.print(f"[dim]URL: {url}[/dim]") + console.print(f"[dim]Destination: {dataset_path}[/dim]") + + try: + # Use curl to download with progress + result = subprocess.run( + ["curl", "-L", "-o", str(dataset_path), url], + capture_output=True, + text=True, + timeout=300 # 5 minute timeout + ) + + if result.returncode == 0 and dataset_path.exists(): + console.print(f"[green]✓ Dataset downloaded successfully[/green]") + return True + else: + console.print(f"[red]✗ Download failed: {result.stderr}[/red]") + return False + + except subprocess.TimeoutExpired: + console.print(f"[red]✗ Download timed out after 5 minutes[/red]") + return False + except Exception as e: + console.print(f"[red]✗ Download error: {e}[/red]") + return False + + def load_dataset(dataset_path: str) -> List[Dict[str, Any]]: """Load LongMemEval dataset from JSON file.""" with open(dataset_path, 'r') as f: @@ -158,7 +196,7 @@ async def ingest_conversation(memory: TemporalSemanticMemory, agent_id: str, ins console.print(f"[yellow]Warning: Failed to ingest session {session_id}: {e}[/yellow]") -def retrieve_memories( +async def retrieve_memories( memory: TemporalSemanticMemory, agent_id: str, query: str, @@ -179,7 +217,7 @@ def retrieve_memories( List of retrieved memory units """ try: - results = memory.search( + results = await memory.search_async( agent_id=agent_id, query=query, thinking_budget=thinking_budget, @@ -323,12 +361,13 @@ def run_benchmark(args): """Run the LongMemEval benchmark evaluation.""" console.print("\n[bold cyan]LongMemEval Benchmark Evaluation[/bold cyan]\n") - # Load dataset + # Load dataset - download if needed dataset_path = Path(__file__).parent / "longmemeval_s_cleaned.json" if not dataset_path.exists(): - console.print(f"[red]Error: Dataset not found at {dataset_path}[/red]") - console.print("[yellow]Run: curl -L 'https://huggingface.co/datasets/xiaowu0162/longmemeval-cleaned/resolve/main/longmemeval_s_cleaned.json' -o longmemeval_s_cleaned.json[/yellow]") - return + if not download_dataset(dataset_path): + console.print(f"[red]Failed to download dataset. Please download manually:[/red]") + console.print("[yellow]curl -L 'https://huggingface.co/datasets/xiaowu0162/longmemeval-cleaned/resolve/main/longmemeval_s_cleaned.json' -o benchmarks/longmemeval/longmemeval_s_cleaned.json[/yellow]") + return console.print(f"[green]Loading dataset from {dataset_path}[/green]") dataset = load_dataset(dataset_path) @@ -374,8 +413,11 @@ def run_benchmark(args): progress.update(instance_task, description=f"[cyan]Instance {idx+1}/{len(dataset)}: {question_id}") - # Create unique agent ID for this instance - agent_id = f"longmemeval_{question_id}" + # Use single agent for all LongMemEval data (cleared per question for isolation) + agent_id = "longmemeval" + + # Clear agent data for this question (each question needs fresh isolated context) + memory.delete_agent(agent_id) # Ingest conversation history try: @@ -385,13 +427,13 @@ def run_benchmark(args): continue # Retrieve memories - memories = retrieve_memories( + memories = asyncio.run(retrieve_memories( memory, agent_id, question, args.thinking_budget, args.top_k - ) + )) # Generate answer predicted_answer = generate_answer(client, question, memories) diff --git a/memory/coref_resolver.py b/memory/coref_resolver.py deleted file mode 100644 index 50ef3ea0..00000000 --- a/memory/coref_resolver.py +++ /dev/null @@ -1,336 +0,0 @@ -""" -Coreference resolution for memory units. - -Ensures every memory unit is self-contained by replacing pronouns -with their actual referents. -""" -import spacy -from typing import List, Dict, Optional -from fastcoref import FCoref -import threading - - -def get_nlp(): - """Get or load spaCy model.""" - try: - return spacy.load("en_core_web_sm") - except OSError: - raise Exception("spaCy model not found. Run: uv pip install https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.7.1/en_core_web_sm-3.7.1-py3-none-any.whl") - - -# Global fastcoref model instance (singleton pattern) -_fastcoref_model = None -_fastcoref_lock = threading.Lock() - - -def get_fastcoref_model(): - """Get or load FastCoref model (singleton pattern).""" - global _fastcoref_model - if _fastcoref_model is None: - with _fastcoref_lock: - if _fastcoref_model is None: - # Use CPU by default, can be configured with device='cuda:0' for GPU - _fastcoref_model = FCoref(device='cpu') - return _fastcoref_model - - -def resolve_pronouns_in_text(text: str, context_sentences: List[str] = None) -> str: - """ - Resolve pronouns to their referents to make text self-contained. - - Strategy: - 1. Identify pronouns in the text - 2. Look for named entities in the same sentence or previous sentences - 3. Replace pronouns with the most likely referent based on: - - Gender agreement - - Number agreement (singular/plural) - - Proximity (closer entities more likely) - - Args: - text: The sentence to resolve - context_sentences: Previous sentences for context (optional) - - Returns: - Text with pronouns resolved - """ - nlp = get_nlp() - - # Parse the target sentence - doc = nlp(text) - - # Collect all sentences for context - all_text = text - if context_sentences: - # Add previous sentences for context - all_text = " ".join(context_sentences) + " " + text - - full_doc = nlp(all_text) - - # Extract entities with their positions - entities = [] - for ent in full_doc.ents: - if ent.label_ in ['PERSON', 'ORG', 'GPE', 'PRODUCT']: - entities.append({ - 'text': ent.text, - 'label': ent.label_, - 'start': ent.start_char, - 'end': ent.end_char, - }) - - # Check if sentence already has a named entity subject - has_named_subject = False - for token in doc: - if token.dep_ in ['nsubj', 'nsubjpass'] and token.pos_ == 'PROPN': - has_named_subject = True - break - - # Find pronouns and anaphoric references that need resolution - pronouns_to_replace = [] - - for token in doc: - # Handle pronouns (he, she, it, they) - if token.pos_ == 'PRON' and token.dep_ in ['nsubj', 'nsubjpass']: - # Subject pronouns that need resolution - pron_lower = token.text.lower() - - # Skip if sentence already has a named subject earlier - if has_named_subject and any( - t.dep_ in ['nsubj', 'nsubjpass'] and t.pos_ == 'PROPN' and t.i < token.i - for t in doc - ): - continue - - # Skip if it's already a proper name or demonstrative - if pron_lower in ['i', 'you', 'we', 'this', 'that', 'these', 'those']: - continue - - # Find the best entity to replace it with - referent = find_best_referent( - pronoun=token, - entities=entities, - doc=full_doc - ) - - if referent: - pronouns_to_replace.append({ - 'pronoun': token, - 'referent': referent, - 'start': token.idx, - 'end': token.idx + len(token.text) - }) - - # Handle definite noun phrases (e.g., "The project") - elif token.text.lower() == 'the' and token.head.pos_ == 'NOUN': - # Check if this "the X" phrase is a subject - if token.head.dep_ in ['nsubj', 'nsubjpass']: - # Try to find what "the X" refers to - noun = token.head.text - # Look for indefinite mentions earlier ("a project", "an organization") - for ent_token in reversed(list(full_doc)): - if ent_token.text.lower() == noun.lower(): - # Found a matching noun - check if it has indefinite article - if any(child.text.lower() in ['a', 'an'] for child in ent_token.children): - # Replace "the project" with "the Python project" or similar - # Get the full noun phrase - descriptors = [] - for child in ent_token.children: - if child.pos_ in ['ADJ', 'PROPN', 'NOUN'] and child.i < ent_token.i: - descriptors.append(child.text) - - if descriptors: - full_phrase = ' '.join(descriptors) + ' ' + noun - # Calculate span to replace - span_start = token.idx - span_end = token.head.idx + len(token.head.text) - - pronouns_to_replace.append({ - 'pronoun': token, - 'referent': 'the ' + full_phrase, - 'start': span_start, - 'end': span_end - }) - break - - # Replace pronouns with referents (in reverse order to maintain indices) - result = text - for item in reversed(pronouns_to_replace): - start = item['start'] - end = item['end'] - result = result[:start] + item['referent'] + result[end:] - - return result - - -def find_best_referent( - pronoun, - entities: List[Dict], - doc -) -> Optional[str]: - """ - Find the best entity referent for a pronoun. - - Uses: - - Gender agreement (he/she -> PERSON) - - Number agreement (singular/plural) - - Entity type (he/she -> PERSON, it -> ORG/PRODUCT) - - Proximity (closer entities preferred) - """ - pron_text = pronoun.text.lower() - - # Determine pronoun properties - is_singular = pron_text in ['he', 'she', 'it', 'him', 'her'] - is_plural = pron_text in ['they', 'them'] - is_person = pron_text in ['he', 'she', 'him', 'her'] - is_thing = pron_text in ['it'] - - # Score each entity - candidates = [] - - for entity in entities: - score = 0.0 - - # Proximity score (entities closer to pronoun are better) - # Since entities come from context, those appearing later (higher start position) are closer - proximity_score = entity['start'] / 1000.0 # Normalize by position - score += proximity_score - - # Type matching - if is_person and entity['label'] == 'PERSON': - score += 2.0 # Strong preference for person entities - elif is_thing and entity['label'] in ['ORG', 'PRODUCT', 'GPE']: - score += 2.0 # Organizations/products for "it" - - # Recency: prefer entities that appear just before the pronoun - if entity['end'] < pronoun.idx: - distance = pronoun.idx - entity['end'] - recency = 1.0 / (1.0 + distance / 100.0) - score += recency - - candidates.append((entity['text'], score)) - - # Return the highest scoring candidate - if candidates: - candidates.sort(key=lambda x: x[1], reverse=True) - return candidates[0][0] - - return None - - -def resolve_sentences_fast(sentences: List[str]) -> List[str]: - """ - Fast batch coreference resolution using FastCoref. - - This is significantly faster than the sequential spaCy-based approach: - - Processes entire document in one pass (O(n) instead of O(n²)) - - Uses efficient batching and neural model - - Can process 2.8K documents in 25 seconds on GPU - - Args: - sentences: List of sentences to resolve - - Returns: - List of resolved sentences (self-contained) - """ - if not sentences: - return [] - - # Join sentences into a single document for batch processing - # Add markers to track sentence boundaries - full_text = " ".join(sentences) - - # Get the fastcoref model - model = get_fastcoref_model() - - # Predict coreferences in batch - preds = model.predict(texts=[full_text]) - - if not preds or len(preds) == 0: - # No coreferences found, return original sentences - return sentences - - # Get the first (and only) result - result = preds[0] - - # Get clusters as text strings - clusters = result.get_clusters(as_strings=True) - - if not clusters: - return sentences - - # Build a replacement map: pronoun -> main referent - replacements = {} - for cluster in clusters: - if len(cluster) < 2: - continue - - # The first mention is typically the most complete referent - main_referent = cluster[0] - - # Map all other mentions (pronouns/short references) to the main referent - for mention in cluster[1:]: - mention_lower = mention.lower() - # Only replace if it's likely a pronoun or short reference - if len(mention.split()) <= 2 and any( - pron in mention_lower - for pron in ['he', 'she', 'it', 'they', 'him', 'her', 'them', 'his', 'her', 'their', 'the'] - ): - replacements[mention] = main_referent - - # Apply replacements to each sentence - resolved = [] - for sentence in sentences: - resolved_sentence = sentence - for mention, referent in replacements.items(): - # Case-insensitive replacement but preserve capitalization context - if mention in resolved_sentence: - resolved_sentence = resolved_sentence.replace(mention, referent) - resolved.append(resolved_sentence) - - return resolved - - -def resolve_sentences(sentences: List[str]) -> List[str]: - """ - Resolve pronouns across a list of sentences. - - Uses FastCoref for efficient batch processing. - Falls back to legacy spaCy method if FastCoref fails. - - Args: - sentences: List of sentences to resolve - - Returns: - List of resolved sentences (self-contained) - """ - try: - return resolve_sentences_fast(sentences) - except Exception as e: - # Fallback to legacy method - print(f"FastCoref failed ({e}), falling back to spaCy method") - return resolve_sentences_legacy(sentences) - - -def resolve_sentences_legacy(sentences: List[str]) -> List[str]: - """ - Legacy sequential pronoun resolution (slower, O(n²) complexity). - - Kept as fallback in case FastCoref is unavailable or fails. - - Args: - sentences: List of sentences to resolve - - Returns: - List of resolved sentences (self-contained) - """ - resolved = [] - - for i, sentence in enumerate(sentences): - # Use all previous sentences as context - context = resolved[:i] if i > 0 else [] - - # Resolve pronouns in this sentence - resolved_sentence = resolve_pronouns_in_text(sentence, context) - - resolved.append(resolved_sentence) - - return resolved diff --git a/memory/entity_resolver.py b/memory/entity_resolver.py index 9743758f..1107318c 100644 --- a/memory/entity_resolver.py +++ b/memory/entity_resolver.py @@ -48,6 +48,43 @@ def extract_entities(text: str) -> List[Dict[str, any]]: return entities +def extract_entities_batch(texts: List[str]) -> List[List[Dict[str, any]]]: + """ + Extract entities from multiple texts in batch (MUCH faster than sequential). + + Uses spaCy's nlp.pipe() for efficient batch processing. + + Args: + texts: List of input texts + + Returns: + List of entity lists, one per input text + """ + if not texts: + return [] + + nlp = get_nlp() + + # Process all texts in batch using nlp.pipe (significantly faster!) + docs = list(nlp.pipe(texts, batch_size=50)) + + all_entities = [] + for doc in docs: + entities = [] + for ent in doc.ents: + # Filter to important entity types + if ent.label_ in ['PERSON', 'ORG', 'GPE', 'LOC', 'PRODUCT', 'EVENT']: + entities.append({ + 'text': ent.text, + 'type': ent.label_, + 'start': ent.start_char, + 'end': ent.end_char, + }) + all_entities.append(entities) + + return all_entities + + class EntityResolver: """ Resolves entities to canonical IDs with disambiguation. @@ -62,6 +99,161 @@ class EntityResolver: """ self.conn = db_conn + def resolve_entities_batch( + self, + agent_id: str, + entities_data: List[Dict], + context: str, + unit_event_date, + ) -> List[str]: + """ + Resolve multiple entities in batch (MUCH faster than sequential). + + Groups entities by type, queries candidates in bulk, and resolves + all entities with minimal DB queries. + + Args: + agent_id: Agent ID + entities_data: List of dicts with 'text', 'type', 'nearby_entities' + context: Context where entities appear + unit_event_date: When this unit was created + + Returns: + List of entity IDs in same order as input + """ + if not entities_data: + return [] + + cursor = self.conn.cursor() + + try: + import time + start = time.time() + + # Group entities by type for efficient querying + entities_by_type = {} + for idx, entity_data in enumerate(entities_data): + entity_type = entity_data['type'] + if entity_type not in entities_by_type: + entities_by_type[entity_type] = [] + entities_by_type[entity_type].append((idx, entity_data)) + + # Query ALL candidates for each type in batch + all_candidates = {} # Maps (entity_type, entity_text) -> list of candidates + for entity_type, entities_list in entities_by_type.items(): + # Extract unique entity texts for this type + entity_texts = list(set(e[1]['text'] for e in entities_list)) + + # Query candidates for all texts at once + from psycopg2.extras import execute_values + cursor.execute( + """ + SELECT canonical_name, id, metadata, last_seen, mention_count + FROM entities + WHERE agent_id = %s AND entity_type = %s + """, + (agent_id, entity_type) + ) + type_candidates = cursor.fetchall() + + # Filter candidates in memory (faster than complex SQL for small datasets) + for entity_text in entity_texts: + matching = [] + entity_text_lower = entity_text.lower() + for canonical_name, ent_id, metadata, last_seen, mention_count in type_candidates: + canonical_lower = canonical_name.lower() + # Same matching logic as before + if (entity_text_lower == canonical_lower or + entity_text_lower in canonical_lower or + canonical_lower in entity_text_lower): + matching.append((ent_id, canonical_name, metadata, last_seen, mention_count)) + all_candidates[(entity_type, entity_text)] = matching + + # Resolve each entity using pre-fetched candidates + entity_ids = [None] * len(entities_data) + entities_to_update = [] # (entity_id, unit_event_date) + entities_to_create = [] # (idx, entity_data) + + for idx, entity_data in enumerate(entities_data): + entity_text = entity_data['text'] + entity_type = entity_data['type'] + nearby_entities = entity_data.get('nearby_entities', []) + + candidates = all_candidates.get((entity_type, entity_text), []) + + if not candidates: + # Will create new entity + entities_to_create.append((idx, entity_data)) + continue + + # Score candidates (same logic as before but with pre-fetched data) + best_candidate = None + best_score = 0.0 + best_name_similarity = 0.0 + + nearby_entity_set = {e['text'].lower() for e in nearby_entities if e['text'] != entity_text} + + for candidate_id, canonical_name, metadata, last_seen, mention_count in candidates: + score = 0.0 + + # Name similarity + name_similarity = SequenceMatcher( + None, + entity_text.lower(), + canonical_name.lower() + ).ratio() + score += name_similarity * 0.5 + + # Temporal proximity + if last_seen: + days_diff = abs((unit_event_date - last_seen).total_seconds() / 86400) + if days_diff < 7: + temporal_score = max(0, 1.0 - (days_diff / 7)) + score += temporal_score * 0.2 + + if score > best_score: + best_score = score + best_candidate = candidate_id + best_name_similarity = name_similarity + + # Apply threshold + threshold = 0.4 if entity_type == 'PERSON' and best_name_similarity >= 0.95 else 0.6 + + if best_score > threshold: + entity_ids[idx] = best_candidate + entities_to_update.append((best_candidate, unit_event_date)) + else: + entities_to_create.append((idx, entity_data)) + + # Batch update existing entities + if entities_to_update: + from psycopg2.extras import execute_values + execute_values( + cursor, + """ + UPDATE entities SET + mention_count = mention_count + 1, + last_seen = data.last_seen + FROM (VALUES %s) AS data(id, last_seen) + WHERE entities.id = data.id::uuid + """, + entities_to_update + ) + + # Batch create new entities + if entities_to_create: + for idx, entity_data in entities_to_create: + entity_id = self._create_entity( + cursor, agent_id, entity_data['text'], + entity_data['type'], unit_event_date + ) + entity_ids[idx] = entity_id + + return entity_ids + + finally: + cursor.close() + def resolve_entity( self, agent_id: str, @@ -297,6 +489,75 @@ class EntityResolver: (entity_id_1, entity_id_2) ) + def link_units_to_entities_batch(self, unit_entity_pairs: List[tuple[str, str]]): + """ + Link multiple memory units to entities in batch (MUCH faster than sequential). + + Also updates co-occurrence cache for entities that appear in the same unit. + + Args: + unit_entity_pairs: List of (unit_id, entity_id) tuples + """ + if not unit_entity_pairs: + return + + cursor = self.conn.cursor() + try: + # Batch insert all unit-entity links + from psycopg2.extras import execute_values + execute_values( + cursor, + """ + INSERT INTO unit_entities (unit_id, entity_id) + VALUES %s + ON CONFLICT DO NOTHING + """, + unit_entity_pairs + ) + + # Build map of unit -> entities for co-occurrence calculation + # Use sets to avoid duplicate entities in the same unit + unit_to_entities = {} + for unit_id, entity_id in unit_entity_pairs: + if unit_id not in unit_to_entities: + unit_to_entities[unit_id] = set() + unit_to_entities[unit_id].add(entity_id) + + # Update co-occurrences for all pairs in each unit + cooccurrence_pairs = set() # Use set to avoid duplicates + for unit_id, entity_ids in unit_to_entities.items(): + entity_list = list(entity_ids) # Convert set to list for iteration + # For each pair of entities in this unit, create co-occurrence + for i, entity_id_1 in enumerate(entity_list): + for entity_id_2 in entity_list[i+1:]: + # Skip if same entity (shouldn't happen with set, but be safe) + if entity_id_1 == entity_id_2: + continue + # Ensure consistent ordering (entity_id_1 < entity_id_2) + if entity_id_1 > entity_id_2: + entity_id_1, entity_id_2 = entity_id_2, entity_id_1 + cooccurrence_pairs.add((entity_id_1, entity_id_2)) + + # Batch update co-occurrences + if cooccurrence_pairs: + from datetime import datetime, timezone + now = datetime.now(timezone.utc) + execute_values( + cursor, + """ + INSERT INTO entity_cooccurrences (entity_id_1, entity_id_2, cooccurrence_count, last_cooccurred) + VALUES %s + ON CONFLICT (entity_id_1, entity_id_2) + DO UPDATE SET + cooccurrence_count = entity_cooccurrences.cooccurrence_count + 1, + last_cooccurred = EXCLUDED.last_cooccurred + """, + [(e1, e2, 1, now) for e1, e2 in cooccurrence_pairs] + ) + + finally: + cursor.close() + def get_units_by_entity(self, entity_id: str, limit: int = 100) -> List[str]: """ Get all units that mention an entity. diff --git a/memory/llm_client.py b/memory/llm_client.py index eb0d28b1..c58c6fcb 100644 --- a/memory/llm_client.py +++ b/memory/llm_client.py @@ -6,6 +6,8 @@ Uses OpenAI-compatible API (works with Groq, OpenAI, etc.) import os import json import re +import asyncio +from datetime import datetime from typing import List, Dict, Optional, Literal from openai import AsyncOpenAI from pydantic import BaseModel, Field @@ -16,16 +18,8 @@ class ExtractedFact(BaseModel): fact: str = Field( description="Self-contained factual statement with subject + action + context" ) - speaker: str = Field( - default="narrator", - description="Who said this (name or 'narrator' if not a conversation)" - ) - type: Literal["biographical", "event", "opinion", "recommendation", "description", "relationship"] = Field( - description="Category of the fact" - ) - confidence: Literal["high", "medium", "low"] = Field( - default="medium", - description="Confidence level of the extraction" + date: str = Field( + description="Absolute date/time when this fact occurred in ISO format (YYYY-MM-DDTHH:MM:SSZ). If text mentions relative time (yesterday, last week, this morning), calculate absolute date from the provided context date." ) @@ -36,75 +30,48 @@ class FactExtractionResponse(BaseModel): ) -def split_into_sentences(text: str) -> List[str]: - """ - Fast sentence splitter using regex. - Splits on periods, exclamation marks, and question marks followed by whitespace or end of string. - - Args: - text: Input text to split - - Returns: - List of sentences - """ - # Split on sentence boundaries: .!? followed by space/newline/end - sentences = re.split(r'(?<=[.!?])\s+', text) - return [s.strip() for s in sentences if s.strip()] - - def chunk_text(text: str, max_chars: int = 120000) -> List[str]: """ - Split text into chunks at sentence boundaries. + Split text into chunks at sentence boundaries using LangChain's text splitter. - Keeps chunks under max_chars (~30k tokens assuming 1 token ≈ 4 chars). - This prevents hitting output token limits on large documents. + Uses RecursiveCharacterTextSplitter which intelligently splits at sentence boundaries + and allows chunks to slightly exceed max_chars to finish sentences naturally. Args: text: Input text to chunk max_chars: Maximum characters per chunk (default 120k ≈ 30k tokens) + Note: chunks may slightly exceed this to complete sentences Returns: - List of text chunks, each under max_chars + List of text chunks, roughly under max_chars """ + from langchain_text_splitters import RecursiveCharacterTextSplitter + # If text is small enough, return as-is if len(text) <= max_chars: return [text] - sentences = split_into_sentences(text) - chunks = [] - current_chunk = [] - current_length = 0 + # Configure splitter to split at sentence boundaries first + # Separators in order of preference: paragraphs, newlines, sentences, words + splitter = RecursiveCharacterTextSplitter( + chunk_size=max_chars, + chunk_overlap=0, + length_function=len, + is_separator_regex=False, + separators=[ + "\n\n", # Paragraph breaks + "\n", # Line breaks + ". ", # Sentence endings + "! ", # Exclamations + "? ", # Questions + "; ", # Semicolons + ", ", # Commas + " ", # Words + "", # Characters (last resort) + ], + ) - for sentence in sentences: - sentence_length = len(sentence) - - # If single sentence exceeds max_chars, split it forcefully - if sentence_length > max_chars: - # Save current chunk if any - if current_chunk: - chunks.append(' '.join(current_chunk)) - current_chunk = [] - current_length = 0 - - # Split long sentence into smaller pieces - for i in range(0, len(sentence), max_chars): - chunks.append(sentence[i:i + max_chars]) - continue - - # If adding this sentence would exceed limit, start new chunk - if current_length + sentence_length + 1 > max_chars: - chunks.append(' '.join(current_chunk)) - current_chunk = [sentence] - current_length = sentence_length - else: - current_chunk.append(sentence) - current_length += sentence_length + 1 # +1 for space - - # Add remaining chunk - if current_chunk: - chunks.append(' '.join(current_chunk)) - - return chunks + return splitter.split_text(text) def get_llm_client() -> AsyncOpenAI: @@ -137,22 +104,28 @@ def get_llm_client() -> AsyncOpenAI: ) -async def extract_facts_from_text( - text: str, - model: str = "openai/gpt-oss-20b", - temperature: float = 0.1, - max_tokens: int = 65000, - chunk_size: int = 60000 +async def _extract_facts_from_chunk( + chunk: str, + chunk_index: int, + total_chunks: int, + event_date: datetime, + context: str, + model: str, + temperature: float, + max_tokens: int, + client: AsyncOpenAI ) -> List[Dict[str, str]]: - client = get_llm_client() + """ + Extract facts from a single chunk (internal helper for parallel processing). + """ + # Format event_date for the prompt + event_date_str = event_date.strftime("%Y-%m-%dT%H:%M:%SZ") - # Chunk text if necessary - chunks = chunk_text(text, max_chars=chunk_size) + prompt = f"""You are extracting facts from text for an AI memory system. Each fact will be stored and retrieved later. - all_facts = [] - - for i, chunk in enumerate(chunks): - prompt = f"""You are extracting facts from text for an AI memory system. Each fact will be stored and retrieved later. +## CONTEXT INFORMATION +- Current reference date/time: {event_date_str} +- Context: {context if context else 'no context provided'} ## CRITICAL: Facts must be DETAILED and COMPREHENSIVE @@ -164,66 +137,158 @@ Each fact should: 5. Include surrounding context that makes the fact meaningful 6. Capture nuances, reasons, causes, and implications -## What to EXTRACT: -- Biographical information (jobs, roles, backgrounds, experiences) -- Events (what happened, when, where, who was involved, why) -- Opinions and beliefs (who believes what and why) -- Recommendations and advice (specific suggestions with reasoning) -- Descriptions (detailed explanations of how things work) -- Relationships (connections between people, organizations, concepts) +## TEMPORAL INFORMATION (VERY IMPORTANT) +For each fact, extract the ABSOLUTE date/time when it occurred: +- If text mentions ABSOLUTE dates ("on March 15, 2024", "last Tuesday"), use that date +- If text mentions RELATIVE times ("yesterday", "last week", "this morning", "3 days ago"), calculate the absolute date using the reference date above. +- if text mentions a vague relative time without a specific day ("last week", "this morning"), transform the date in relative with absolute context ("last week" + " 2 june 2024" -> "week before June 2 2024") in the text and use the absolute date for the 'date' field +- If NO specific time is mentioned, use the reference date +- Always output dates in ISO format: YYYY-MM-DDTHH:MM:SSZ -## What to SKIP: -- Greetings, thank yous, acknowledgments +Examples of date extraction: +- Reference: 2024-03-20T10:00:00Z +- "Yesterday I went hiking" → date: 2024-03-19T10:00:00Z +- "Last week I joined Google" → date: 2024-03-13T10:00:00Z (approximately) +- "This morning I had coffee" → date: 2024-03-20T08:00:00Z +- "I work at Google" (no time mentioned) → date: 2024-03-20T10:00:00Z (use reference) + +## What to EXTRACT (BE EXHAUSTIVE - DO NOT SKIP ANYTHING): +- **Biographical information**: jobs, roles, backgrounds, experiences, skills +- **Events (NEVER MISS THESE)**: + - ANY action that happened (went, did, attended, joined, started, finished, etc.) + - Photos, images, videos shared or taken ("here's a photo", "took a picture", "captured") + - Social activities (meetups, gatherings, meals, conversations) + - Achievements, milestones, accomplishments + - Travels, visits, locations visited + - Purchases, acquisitions, creations +- **Opinions and beliefs**: who believes what and why +- **Recommendations and advice**: specific suggestions with reasoning +- **Descriptions**: detailed explanations of how things work +- **Relationships**: connections between people, organizations, concepts +- **States and conditions**: current status, ongoing situations + +## CRITICAL: Extract EVERY event mentioned, even casual ones +- "here's a photo of X" = someone took/shared a photo of X +- "I was with friends last week" = meetup/gathering with friends last week +- "sent you that link" = action of sending a link +- DO NOT skip events just because they seem minor or casual + +## What to SKIP (ONLY these): +- Greetings, thank yous, acknowledgments (unless they reveal information) - Filler words ("um", "uh", "like") -- Pure reactions without content ("wow", "cool") -- Incomplete thoughts +- Pure reactions without content ("wow", "cool", "nice") +- Incomplete thoughts or sentence fragments with no meaning ## EXAMPLES of GOOD facts (detailed, comprehensive): -Input: "Alice mentioned she works at Google in Mountain View. She joined the AI team last year and loves working on large language models." -GOOD: "Alice works at Google in Mountain View on the AI team, which she joined last year, and she loves working on large language models" -BAD: "Alice works at Google" (too short, missing context) +Input: "Alice mentioned she works at Google in Mountain View. She joined the AI team last year." +GOOD fact: "Alice works at Google in Mountain View on the AI team, which she joined last year" +GOOD date: Calculate based on reference date (if reference is 2024-03-20, "last year" = 2023-03-20) -Input: "Bob said he's been hiking every weekend in Yosemite because it helps him clear his mind after stressful work weeks." -GOOD: "Bob has been hiking every weekend in Yosemite because it helps him clear his mind after stressful work weeks" -BAD: "Bob hikes in Yosemite" (missing frequency, reason, and context) +Input: "Yesterday Bob went hiking in Yosemite because it helps him clear his mind." +GOOD fact: "Bob went hiking in Yosemite because it helps him clear his mind" +GOOD date: Reference date minus 1 day -Input: "The new algorithm reduced latency by 40% compared to the baseline by using a novel caching strategy." -GOOD: "The new algorithm reduced latency by 40% compared to the baseline by using a novel caching strategy" -BAD: "The algorithm is faster" (missing numbers, comparison, and method) +Input: "Here's a photo of me with my friends taken last week at the beach." +GOOD fact: "Someone shared/took a photo with their friends at the beach" +GOOD date: Reference date minus 7 days (last week) +NOTE: Extract the event (photo taken/shared with friends at beach), NOT just that a photo exists + +Input: "I sent you that article about AI last Tuesday." +GOOD fact: "Someone sent an article about AI" +GOOD date: Calculate last Tuesday from reference date ## TEXT TO EXTRACT FROM: {chunk} -Remember: Include ALL details, names, numbers, reasons, and context. Facts should be rich and informative, not summaries.""" +Remember: +1. BE EXHAUSTIVE - Extract EVERY event, action, and fact mentioned +2. DO NOT skip casual mentions like "here's a photo", "I was with X", "sent you Y" +3. Include ALL details, names, numbers, reasons, and context in the fact text +4. Extract the absolute date for EACH fact by calculating relative times from the reference date +5. When in doubt, EXTRACT IT - better to have too many facts than miss important events""" - # Use parse() for structured outputs with Pydantic models - response = await client.beta.chat.completions.parse( + response = await client.beta.chat.completions.parse( + model=model, + messages=[ + { + "role": "system", + "content": "You are an EXHAUSTIVE fact extractor. Extract EVERY event, action, and fact mentioned - never skip anything. This includes casual mentions like photos shared, things sent, meetups, gatherings, or any action. Preserve all context, details, and nuances. Calculate absolute dates from relative time expressions. When in doubt, extract it - missing facts is worse than extracting too many." + }, + { + "role": "user", + "content": prompt + } + ], + temperature=temperature, + max_tokens=max_tokens, + response_format=FactExtractionResponse, + extra_body={"service_tier": "auto"}, + ) + + # Extract the parsed response + extraction_response = response.choices[0].message.parsed + + # Convert to dict format + chunk_facts = [fact.model_dump() for fact in extraction_response.facts] + + return chunk_facts + + +async def extract_facts_from_text( + text: str, + event_date: datetime, + context: str = "", + model: str = "openai/gpt-oss-120b", + temperature: float = 0.1, + max_tokens: int = 65000, + chunk_size: int = 5000 +) -> List[Dict[str, str]]: + """ + Extract semantic facts from conversational or narrative text using LLM. + + For large texts (>chunk_size chars), automatically chunks at sentence boundaries + to avoid hitting output token limits. Processes ALL chunks in PARALLEL for speed. + + Args: + text: Input text (conversation, article, etc.) + event_date: Reference date for resolving relative times + context: Context about the conversation/document + model: LLM model to use + temperature: Sampling temperature (lower = more focused) + max_tokens: Maximum tokens in response + chunk_size: Maximum characters per chunk + + Returns: + List of fact dictionaries with 'fact' and 'date' keys + """ + client = get_llm_client() + + # Chunk text if necessary + chunks = chunk_text(text, max_chars=chunk_size) + + # Process all chunks in parallel using asyncio.gather + tasks = [ + _extract_facts_from_chunk( + chunk=chunk, + chunk_index=i, + total_chunks=len(chunks), + event_date=event_date, + context=context, model=model, - messages=[ - { - "role": "system", - "content": "You extract detailed, comprehensive facts from text. Preserve all context, details, and nuances. Never summarize or shorten - include everything relevant." - }, - { - "role": "user", - "content": prompt - } - ], temperature=temperature, max_tokens=max_tokens, - response_format=FactExtractionResponse + client=client ) + for i, chunk in enumerate(chunks) + ] - # Extract the parsed response - extraction_response = response.choices[0].message.parsed + # Wait for all chunks to complete in parallel + chunk_results = await asyncio.gather(*tasks) - # Convert to dict format and add to aggregate - chunk_facts = [fact.model_dump() for fact in extraction_response.facts] + # Flatten results from all chunks + all_facts = [] + for chunk_facts in chunk_results: all_facts.extend(chunk_facts) - # Log progress for large documents - if len(chunks) > 1: - print(f"Processed chunk {i + 1}/{len(chunks)}: extracted {len(chunk_facts)} facts") - return all_facts diff --git a/memory/temporal_semantic_memory.py b/memory/temporal_semantic_memory.py index f5ee7dba..9e012a21 100644 --- a/memory/temporal_semantic_memory.py +++ b/memory/temporal_semantic_memory.py @@ -18,14 +18,15 @@ from sentence_transformers import SentenceTransformer from dotenv import load_dotenv import asyncio import time +from concurrent.futures import ProcessPoolExecutor +import numpy as np from .utils import ( extract_facts, calculate_recency_weight, calculate_frequency_weight, ) -from .entity_resolver import EntityResolver, extract_entities -from .coref_resolver import resolve_sentences +from .entity_resolver import EntityResolver def utcnow(): @@ -33,6 +34,45 @@ def utcnow(): return datetime.now(timezone.utc) +# Global process pool for parallel embedding generation +# Each process loads its own copy of the embedding model +# This provides TRUE parallelism for CPU-bound embedding operations +_PROCESS_POOL = None +_EMBEDDING_MODEL_NAME = "BAAI/bge-small-en-v1.5" + +# Process-local model cache (one per worker process) +_worker_model = None + + +def _get_worker_model(): + """Get or load the embedding model in worker process.""" + global _worker_model + if _worker_model is None: + _worker_model = SentenceTransformer(_EMBEDDING_MODEL_NAME) + return _worker_model + + +def _encode_batch_worker(texts: List[str]) -> List[List[float]]: + """ + Worker function for process pool - encodes texts to embeddings. + + This function runs in a separate process and loads its own model. + """ + model = _get_worker_model() + embeddings = model.encode(texts, convert_to_numpy=True, show_progress_bar=False) + return [emb.tolist() for emb in embeddings] + + +def _get_process_pool(): + """Get or create the global process pool.""" + global _PROCESS_POOL + if _PROCESS_POOL is None: + # Use 4 worker processes for true parallelism + # Adjust based on your CPU cores (each process loads ~500MB model) + _PROCESS_POOL = ProcessPoolExecutor(max_workers=4) + return _PROCESS_POOL + + class TemporalSemanticMemory: """ Advanced memory system using temporal and semantic linking with PostgreSQL. @@ -94,11 +134,13 @@ class TemporalSemanticMemory: async def _generate_embeddings_batch(self, texts: List[str]) -> List[List[float]]: """ - Generate embeddings for multiple texts using local model (batch processing). + Generate embeddings for multiple texts using local model in parallel. - Local models are fast and process batches efficiently without needing - parallel API calls. We run this in asyncio to avoid blocking, but the - actual embedding generation is synchronous. + Uses a ProcessPoolExecutor to achieve TRUE parallelism for CPU-bound + embedding generation. Each worker process loads its own model copy. + + When multiple put_async calls run in parallel, each can generate + embeddings concurrently in separate processes (no GIL contention). Args: texts: List of texts to embed @@ -107,13 +149,15 @@ class TemporalSemanticMemory: List of 384-dimensional embeddings in same order as input texts """ try: - # Run in thread pool to avoid blocking event loop + # Run in process pool for true parallelism loop = asyncio.get_event_loop() + pool = _get_process_pool() embeddings = await loop.run_in_executor( - None, - lambda: self.embedding_model.encode(texts, convert_to_numpy=True, show_progress_bar=False) + pool, + _encode_batch_worker, + texts ) - return [emb.tolist() for emb in embeddings] + return embeddings except Exception as e: raise Exception(f"Failed to generate batch embeddings: {str(e)}") @@ -208,14 +252,7 @@ class TemporalSemanticMemory: """ Store content as memory units with temporal and semantic links (ASYNC version). - This async version generates ALL embeddings in parallel for maximum speed, - then uses batch inserts for database operations. - - Steps: - 1. Split content into sentence units - 2. Resolve coreferences - 3. **Generate ALL embeddings in parallel** (FAST!) - 4. **Batch insert all units and links** (FAST!) + This is a convenience wrapper around put_batch_async for a single content item. Args: agent_id: Unique identifier for the agent @@ -226,131 +263,212 @@ class TemporalSemanticMemory: Returns: List of created unit IDs """ + # Use put_batch_async with a single item (avoids code duplication) + result = await self.put_batch_async( + agent_id=agent_id, + contents=[{ + "content": content, + "context": context, + "event_date": event_date + }] + ) + + # Return the first (and only) list of unit IDs + return result[0] if result else [] + + async def put_batch_async( + self, + agent_id: str, + contents: List[Dict[str, Any]], + ) -> List[List[str]]: + """ + Store multiple content items as memory units in ONE batch operation. + + This is MUCH more efficient than calling put_async multiple times: + - Extracts facts from all contents in parallel + - Generates ALL embeddings in ONE batch + - Does ALL database operations in ONE transaction + + Args: + agent_id: Unique identifier for the agent + contents: List of dicts with keys: + - "content" (required): Text content to store + - "context" (optional): Context about the memory + - "event_date" (optional): When the event occurred + + Returns: + List of lists of unit IDs (one list per content item) + + Example: + unit_ids = await memory.put_batch_async( + agent_id="user123", + contents=[ + {"content": "Alice works at Google", "context": "conversation"}, + {"content": "Bob loves Python", "context": "conversation"}, + ] + ) + # Returns: [["unit-id-1"], ["unit-id-2"]] + """ start_time = time.time() print(f"\n{'='*60}") - print(f"PUT_ASYNC START: {agent_id}") - print(f"Content length: {len(content)} chars") + print(f"PUT_BATCH_ASYNC START: {agent_id}") + print(f"Batch size: {len(contents)} content items") print(f"{'='*60}") - if event_date is None: - event_date = utcnow() - - # Step 1: Extract semantic facts using LLM (async) - step_start = time.time() - try: - facts = await extract_facts(content) - print(f"[1] Extract facts: {len(facts)} facts in {time.time() - step_start:.3f}s") - except Exception as e: - print(f"\n{'='*60}") - print(f"PUT_ASYNC FAILED: Fact extraction error") - print(f"Error: {e}") - print(f"{'='*60}\n") - raise Exception(f"Failed to extract facts from content: {e}") - - # Step 2: Resolve pronouns to make facts even more self-contained - step_start = time.time() - sentences = resolve_sentences(facts) - print(f"[2] Resolve coreferences: {time.time() - step_start:.3f}s") - - # Step 3: Generate ALL embeddings in parallel - step_start = time.time() - embeddings = await self._generate_embeddings_batch(sentences) - print(f"[3] Generate embeddings (parallel): {len(embeddings)} embeddings in {time.time() - step_start:.3f}s") - - # Step 4: Check for duplicates using similarity + temporal window - cursor = self.conn.cursor() - step_start = time.time() - duplicate_flags = self._find_duplicate_facts_batch( - cursor, agent_id, sentences, embeddings, event_date - ) - num_duplicates = sum(duplicate_flags) - - # Filter out duplicates - filtered_data = [ - (sentence, embedding) - for sentence, embedding, is_dup in zip(sentences, embeddings, duplicate_flags) - if not is_dup - ] - - if filtered_data: - sentences, embeddings = zip(*filtered_data) - sentences = list(sentences) - embeddings = list(embeddings) - else: - sentences = [] - embeddings = [] - - print(f"[4] Deduplication check: {num_duplicates} duplicates filtered, {len(sentences)} new facts in {time.time() - step_start:.3f}s") - - # If all facts were duplicates, return empty list - if not sentences: - cursor.close() - print(f"\n{'='*60}") - print(f"PUT_ASYNC COMPLETE: All facts were duplicates, nothing stored") - print(f"{'='*60}\n") + if not contents: return [] - # Step 5: Batch insert everything + # Step 1: Extract facts from ALL contents in parallel + step_start = time.time() + + # Create tasks for parallel fact extraction + fact_extraction_tasks = [] + for item in contents: + content = item["content"] + context = item.get("context", "") + event_date = item.get("event_date") or utcnow() + + task = extract_facts(content, event_date, context) + fact_extraction_tasks.append((task, event_date, context)) + + # Wait for all fact extractions to complete + all_fact_results = await asyncio.gather(*[task for task, _, _ in fact_extraction_tasks]) + + # Flatten and track which facts belong to which content + all_fact_texts = [] + all_fact_dates = [] + all_contexts = [] + content_boundaries = [] # [(start_idx, end_idx), ...] + + current_idx = 0 + for i, ((_, event_date, context), fact_dicts) in enumerate(zip(fact_extraction_tasks, all_fact_results)): + start_idx = current_idx + + for fact_dict in fact_dicts: + all_fact_texts.append(fact_dict['fact']) + try: + from dateutil import parser as date_parser + fact_date = date_parser.isoparse(fact_dict['date']) + all_fact_dates.append(fact_date) + except Exception: + all_fact_dates.append(event_date) + all_contexts.append(context) + + end_idx = current_idx + len(fact_dicts) + content_boundaries.append((start_idx, end_idx)) + current_idx = end_idx + + total_facts = len(all_fact_texts) + + if total_facts == 0: + return [[] for _ in contents] + + # Step 2: Generate ALL embeddings in ONE batch (HUGE speedup!) + step_start = time.time() + all_embeddings = await self._generate_embeddings_batch(all_fact_texts) + print(f"[2] Generate embeddings (parallel): {len(all_embeddings)} embeddings in {time.time() - step_start:.3f}s") + + # Step 3: Process everything in ONE database transaction + cursor = self.conn.cursor() try: - # Batch INSERT all memory units + # Deduplication check for all facts + step_start = time.time() + all_is_duplicate = [] + for sentence, embedding, fact_date in zip(all_fact_texts, all_embeddings, all_fact_dates): + dup_flags = self._find_duplicate_facts_batch( + cursor, agent_id, [sentence], [embedding], fact_date + ) + all_is_duplicate.extend(dup_flags) + + duplicates_filtered = sum(all_is_duplicate) + new_facts = total_facts - duplicates_filtered + print(f"[3] Deduplication check: {duplicates_filtered} duplicates filtered, {new_facts} new facts in {time.time() - step_start:.3f}s") + + # Filter out duplicates + filtered_sentences = [s for s, is_dup in zip(all_fact_texts, all_is_duplicate) if not is_dup] + filtered_embeddings = [e for e, is_dup in zip(all_embeddings, all_is_duplicate) if not is_dup] + filtered_dates = [d for d, is_dup in zip(all_fact_dates, all_is_duplicate) if not is_dup] + filtered_contexts = [c for c, is_dup in zip(all_contexts, all_is_duplicate) if not is_dup] + + if not filtered_sentences: + print(f"[PUT_BATCH_ASYNC] All facts were duplicates, returning empty") + return [[] for _ in contents] + + # Batch insert ALL units step_start = time.time() from psycopg2.extras import execute_values unit_data = [ - (agent_id, sentence, embedding, context, event_date, 0) - for sentence, embedding in zip(sentences, embeddings) + (agent_id, sentence, context, embedding, date, 0) # access_count starts at 0 + for sentence, context, embedding, date in zip( + filtered_sentences, filtered_contexts, filtered_embeddings, filtered_dates + ) ] - unit_ids = execute_values( + results = execute_values( cursor, """ - INSERT INTO memory_units (agent_id, text, embedding, context, event_date, access_count) + INSERT INTO memory_units (agent_id, text, context, embedding, event_date, access_count) VALUES %s RETURNING id """, unit_data, fetch=True ) - created_unit_ids = [str(row[0]) for row in unit_ids] - print(f"[5] Batch insert units: {time.time() - step_start:.3f}s") - # Process entities for all units - step_start = time.time() - all_entity_links = [] - for unit_id, sentence in zip(created_unit_ids, sentences): - entity_links = self._extract_entities_for_batch(cursor, agent_id, unit_id, sentence, context, event_date, sentences) - all_entity_links.extend(entity_links) - print(f"[6] Extract entities: {time.time() - step_start:.3f}s") + created_unit_ids = [str(row[0]) for row in results] + print(f"[5] Batch insert units: {len(created_unit_ids)} units in {time.time() - step_start:.3f}s") - # Create ALL temporal links in batch + # Process entities for ALL units step_start = time.time() - self._create_temporal_links_batch(cursor, agent_id, created_unit_ids, event_date) + all_entity_links = self._extract_entities_batch_optimized( + cursor, agent_id, created_unit_ids, filtered_sentences, "", filtered_dates + ) + print(f"[6] Extract entities (batched): {time.time() - step_start:.3f}s") + + # Create temporal links + step_start = time.time() + self._create_temporal_links_batch_per_fact(cursor, agent_id, created_unit_ids) print(f"[7] Batch create temporal links: {time.time() - step_start:.3f}s") - # Create ALL semantic links in batch + # Create semantic links step_start = time.time() - self._create_semantic_links_batch(cursor, agent_id, created_unit_ids, embeddings) + self._create_semantic_links_batch(cursor, agent_id, created_unit_ids, filtered_embeddings) print(f"[8] Batch create semantic links: {time.time() - step_start:.3f}s") - # Insert all entity links in batch + # Insert entity links step_start = time.time() if all_entity_links: self._insert_entity_links_batch(cursor, all_entity_links) print(f"[9] Batch insert entity links: {time.time() - step_start:.3f}s") + # Commit everything commit_start = time.time() self.conn.commit() print(f"[10] Commit: {time.time() - commit_start:.3f}s") + # Map created unit IDs back to original content items + # Account for duplicates when mapping back + result_unit_ids = [] + filtered_idx = 0 + + for start_idx, end_idx in content_boundaries: + content_unit_ids = [] + for i in range(start_idx, end_idx): + if not all_is_duplicate[i]: + content_unit_ids.append(created_unit_ids[filtered_idx]) + filtered_idx += 1 + result_unit_ids.append(content_unit_ids) + total_time = time.time() - start_time print(f"\n{'='*60}") - print(f"PUT_ASYNC COMPLETE: {len(created_unit_ids)} units stored in {total_time:.3f}s") + print(f"PUT_BATCH_ASYNC COMPLETE: {len(created_unit_ids)} units from {len(contents)} contents in {total_time:.3f}s") print(f"{'='*60}\n") - return created_unit_ids + return result_unit_ids except Exception as e: self.conn.rollback() - raise Exception(f"Failed to store memory: {str(e)}") + raise Exception(f"Failed to store batch memory: {str(e)}") finally: cursor.close() @@ -412,7 +530,11 @@ class TemporalSemanticMemory: ) except Exception as e: - print(f"Warning: Failed to create temporal links: {str(e)}") + print(f"ERROR: Failed to create temporal links: {str(e)}") + import traceback + traceback.print_exc() + # Re-raise to trigger rollback at put_async level + raise def _create_semantic_links( self, @@ -471,77 +593,11 @@ class TemporalSemanticMemory: ) except Exception as e: - print(f"Warning: Failed to create semantic links: {str(e)}") - - def _extract_and_link_entities( - self, - cursor, - agent_id: str, - unit_id: str, - text: str, - context: str, - event_date, - all_sentences: List[str], - ): - """ - Extract entities from text, resolve them, and create entity links. - - Args: - cursor: Database cursor - agent_id: Agent ID - unit_id: Current unit ID - text: Unit text - context: Context - event_date: When created - all_sentences: All sentences from the same PUT (for context) - """ - try: - # Extract entities from this unit - entities = extract_entities(text) - - if not entities: - return - - # Resolve each entity and link - entity_ids = [] - for entity in entities: - entity_id = self.entity_resolver.resolve_entity( - agent_id=agent_id, - entity_text=entity['text'], - entity_type=entity['type'], - context=context, - nearby_entities=entities, - unit_event_date=event_date - ) - entity_ids.append(entity_id) - - # Link unit to entity - self.entity_resolver.link_unit_to_entity(unit_id, entity_id) - - # Create entity links to other units that mention the same entities - for entity_id in set(entity_ids): - # Get other units that mention this entity - related_units = self.entity_resolver.get_units_by_entity(entity_id, limit=50) - - # Create entity links - links = [] - for related_unit_id in related_units: - if str(related_unit_id) != str(unit_id): - links.append((unit_id, related_unit_id, 'entity', 1.0, entity_id)) - - if links: - execute_values( - cursor, - """ - INSERT INTO memory_links (from_unit_id, to_unit_id, link_type, weight, entity_id) - VALUES %s - ON CONFLICT DO NOTHING - """, - links - ) - - except Exception as e: - print(f"Warning: Failed to extract/link entities: {str(e)}") + print(f"ERROR: Failed to create semantic links: {str(e)}") + import traceback + traceback.print_exc() + # Re-raise to trigger rollback at put_async level + raise def search( self, @@ -552,7 +608,34 @@ class TemporalSemanticMemory: live_tracer=None, ) -> List[Dict[str, Any]]: """ - Search memories using spreading activation. + Search memories using spreading activation (synchronous wrapper). + + This is a synchronous wrapper around search_async() for convenience. + For best performance, use search_async() directly. + + Args: + agent_id: Agent ID to search for + query: Search query + thinking_budget: How many units to explore (computational budget) + top_k: Number of results to return + live_tracer: Optional LiveSearchTracer for visualization + + Returns: + List of memory units with their weights, sorted by relevance + """ + # Run async version synchronously + return asyncio.run(self.search_async(agent_id, query, thinking_budget, top_k, live_tracer)) + + async def search_async( + self, + agent_id: str, + query: str, + thinking_budget: int = 50, + top_k: int = 10, + live_tracer=None, + ) -> List[Dict[str, Any]]: + """ + Search memories using spreading activation (ASYNC version). This implements the core SEARCH operation: 1. Find entry points (most relevant units via vector search) @@ -572,14 +655,20 @@ class TemporalSemanticMemory: """ cursor = self.conn.cursor(cursor_factory=RealDictCursor) + search_start = time.time() + print(f"\n[SEARCH] Starting search for query: '{query[:50]}...' (thinking_budget={thinking_budget}, top_k={top_k})") + try: # Step 1: Generate query embedding + step_start = time.time() query_embedding = self._generate_embedding(query) + print(f" [1] Generate query embedding: {time.time() - step_start:.3f}s") # Step 2: Find entry points + step_start = time.time() cursor.execute( """ - SELECT id, text, context, event_date, access_count, + SELECT id, text, context, event_date, access_count, embedding, 1 - (embedding <=> %s::vector) AS similarity FROM memory_units WHERE agent_id = %s @@ -592,104 +681,230 @@ class TemporalSemanticMemory: ) entry_points = cursor.fetchall() + print(f" [2] Find entry points: {len(entry_points)} found in {time.time() - step_start:.3f}s") + if not entry_points: + print(f"[SEARCH] Complete: 0 results in {time.time() - search_start:.3f}s") return [] # Step 3: Spreading activation with budget + step_start = time.time() visited = set() results = [] budget_remaining = thinking_budget - queue = [(dict(unit), 1.0, True) for unit in entry_points] # (unit, activation, is_entry) + # Initialize entry points with their actual similarity scores instead of 1.0 + queue = [(dict(unit), unit["similarity"], True) for unit in entry_points] # (unit, activation, is_entry) + + # Track substep timings + update_access_time = 0 + calculate_weight_time = 0 + query_neighbors_time = 0 + process_neighbors_time = 0 + + # Process nodes in batches for efficient neighbor querying + BATCH_SIZE = 50 + nodes_to_process = [] # (unit, activation, is_entry_point) while queue and budget_remaining > 0: - current_unit, activation, is_entry_point = queue.pop(0) - unit_id = str(current_unit["id"]) + # Collect a batch of nodes to process + while queue and len(nodes_to_process) < BATCH_SIZE and budget_remaining > 0: + current_unit, activation, is_entry_point = queue.pop(0) + unit_id = str(current_unit["id"]) - if unit_id in visited: - continue + if unit_id not in visited: + visited.add(unit_id) + budget_remaining -= 1 + nodes_to_process.append((current_unit, activation, is_entry_point)) - visited.add(unit_id) - budget_remaining -= 1 + if not nodes_to_process: + break - # Increment access count + # Update access counts for batch + substep_start = time.time() + node_ids = [str(node[0]["id"]) for node in nodes_to_process] cursor.execute( - "UPDATE memory_units SET access_count = access_count + 1 WHERE id = %s", - (unit_id,) + "UPDATE memory_units SET access_count = access_count + 1 WHERE id::text = ANY(%s)", + (node_ids,) ) + update_access_time += time.time() - substep_start - # Calculate combined weight - event_date = current_unit["event_date"] - days_since = (utcnow() - event_date).total_seconds() / 86400 - - recency_weight = calculate_recency_weight(days_since) - frequency_weight = calculate_frequency_weight(current_unit.get("access_count", 0)) - - # Combined weight: activation * recency * frequency - final_weight = activation * recency_weight * frequency_weight - - # Notify tracer - if live_tracer: - live_tracer.visit_node( - node_id=unit_id, - text=current_unit["text"], - activation=activation, - recency=recency_weight, - frequency=frequency_weight, - weight=final_weight, - is_entry_point=is_entry_point, - ) - import time - time.sleep(0.15) # Slow down for visualization - - results.append({ - "id": unit_id, - "text": current_unit["text"], - "context": current_unit.get("context", ""), - "event_date": event_date.isoformat(), - "weight": final_weight, - "activation": activation, - "recency": recency_weight, - "frequency": frequency_weight, - }) - - # Spread to neighbors + # Query neighbors for ALL nodes in batch at once + substep_start = time.time() cursor.execute( """ - SELECT ml.to_unit_id, ml.weight, mu.text, mu.context, mu.event_date, mu.access_count + SELECT ml.from_unit_id, ml.to_unit_id, ml.weight, + mu.text, mu.context, mu.event_date, mu.access_count, mu.embedding FROM memory_links ml JOIN memory_units mu ON ml.to_unit_id = mu.id - WHERE ml.from_unit_id = %s + WHERE ml.from_unit_id::text = ANY(%s) AND ml.weight >= 0.1 - ORDER BY ml.weight DESC + ORDER BY ml.from_unit_id, ml.weight DESC """, - (unit_id,) + (node_ids,) ) + all_neighbors = cursor.fetchall() + query_neighbors_time += time.time() - substep_start - neighbors = cursor.fetchall() - for neighbor in neighbors: - neighbor_id = str(neighbor["to_unit_id"]) - if neighbor_id not in visited: - link_weight = neighbor["weight"] - new_activation = activation * link_weight * 0.8 # 0.8 = decay factor + # Group neighbors by from_unit_id + substep_start = time.time() + neighbors_by_node = {} + for neighbor in all_neighbors: + from_id = str(neighbor["from_unit_id"]) + if from_id not in neighbors_by_node: + neighbors_by_node[from_id] = [] + neighbors_by_node[from_id].append(neighbor) - if new_activation > 0.1: - queue.append(({ - "id": neighbor["to_unit_id"], - "text": neighbor["text"], - "context": neighbor.get("context", ""), - "event_date": neighbor["event_date"], - "access_count": neighbor["access_count"], - }, new_activation, False)) # Not an entry point + # Process each node in the batch + for current_unit, activation, is_entry_point in nodes_to_process: + unit_id = str(current_unit["id"]) + + # Calculate combined weight + event_date = current_unit["event_date"] + days_since = (utcnow() - event_date).total_seconds() / 86400 + + recency_weight = calculate_recency_weight(days_since) + frequency_weight = calculate_frequency_weight(current_unit.get("access_count", 0)) + + # Normalize frequency to [0, 1] range + frequency_normalized = (frequency_weight - 1.0) / 1.0 + + # Calculate semantic similarity between query and this memory + memory_embedding = current_unit.get("embedding") + if memory_embedding is not None: + # Cosine similarity = 1 - cosine distance + query_vec = np.array(query_embedding) + memory_vec = np.array(memory_embedding) + # Cosine similarity + dot_product = np.dot(query_vec, memory_vec) + norm_query = np.linalg.norm(query_vec) + norm_memory = np.linalg.norm(memory_vec) + semantic_similarity = dot_product / (norm_query * norm_memory) if norm_query > 0 and norm_memory > 0 else 0.0 + else: + semantic_similarity = 0.0 + + # Combined weight: 30% activation, 30% semantic similarity, 25% recency, 15% frequency + final_weight = 0.3 * activation + 0.3 * semantic_similarity + 0.25 * recency_weight + 0.15 * frequency_normalized + + # Notify tracer + if live_tracer: + live_tracer.visit_node( + node_id=unit_id, + text=current_unit["text"], + activation=activation, + recency=recency_weight, + frequency=frequency_weight, + weight=final_weight, + is_entry_point=is_entry_point, + ) + + results.append({ + "id": unit_id, + "text": current_unit["text"], + "context": current_unit.get("context", ""), + "event_date": event_date.isoformat(), + "weight": final_weight, + "activation": activation, + "semantic_similarity": semantic_similarity, + "recency": recency_weight, + "frequency": frequency_weight, + }) + + # Spread to neighbors (from batch query results) + neighbors = neighbors_by_node.get(unit_id, []) + for neighbor in neighbors: + neighbor_id = str(neighbor["to_unit_id"]) + if neighbor_id not in visited: + link_weight = neighbor["weight"] + new_activation = activation * link_weight * 0.8 # 0.8 = decay factor + + if new_activation > 0.1: + queue.append(({ + "id": neighbor["to_unit_id"], + "text": neighbor["text"], + "context": neighbor.get("context", ""), + "event_date": neighbor["event_date"], + "access_count": neighbor["access_count"], + "embedding": neighbor.get("embedding"), + }, new_activation, False)) # Not an entry point + + calculate_weight_time += time.time() - substep_start + process_neighbors_time += time.time() - substep_start + + # Clear batch for next iteration + nodes_to_process = [] + + spreading_activation_time = time.time() - step_start + num_batches = (len(visited) + BATCH_SIZE - 1) // BATCH_SIZE # Ceiling division + print(f" [3] Spreading activation: {len(visited)} nodes visited in {spreading_activation_time:.3f}s") + print(f" [3.1] Update access counts: {update_access_time:.3f}s") + print(f" [3.2] Calculate weights: {calculate_weight_time:.3f}s") + print(f" [3.3] Query neighbors: {query_neighbors_time:.3f}s ({num_batches} batched queries)") + print(f" [3.4] Process neighbors: {process_neighbors_time:.3f}s") + + step_start = time.time() + self.conn.commit() + print(f" [4] Commit: {time.time() - step_start:.3f}s") + + # Step 4: Sort by final weight and return top results + step_start = time.time() + results.sort(key=lambda x: x["weight"], reverse=True) + top_results = results[:top_k] + print(f" [5] Sort and return top {top_k}: {time.time() - step_start:.3f}s") + + print(f"[SEARCH] Complete: {len(top_results)} results in {time.time() - search_start:.3f}s\n") + return top_results + + except Exception as e: + print(f"[SEARCH] ERROR after {time.time() - search_start:.3f}s: {str(e)}") + self.conn.rollback() + raise Exception(f"Failed to search memories: {str(e)}") + finally: + cursor.close() + + def delete_agent(self, agent_id: str) -> Dict[str, int]: + """ + Delete all data for a specific agent (multi-tenant cleanup). + + This is much more efficient than dropping all tables and allows + multiple agents to coexist in the same database. + + Deletes (with CASCADE): + - All memory units for this agent + - All entities for this agent + - All associated links, unit-entity associations, and co-occurrences + + Args: + agent_id: Agent ID to delete + + Returns: + Dictionary with counts of deleted items + """ + cursor = self.conn.cursor() + + try: + # Count before deletion for reporting + cursor.execute("SELECT COUNT(*) FROM memory_units WHERE agent_id = %s", (agent_id,)) + units_count = cursor.fetchone()[0] + + cursor.execute("SELECT COUNT(*) FROM entities WHERE agent_id = %s", (agent_id,)) + entities_count = cursor.fetchone()[0] + + # Delete memory units (cascades to unit_entities, memory_links) + cursor.execute("DELETE FROM memory_units WHERE agent_id = %s", (agent_id,)) + + # Delete entities (cascades to unit_entities, entity_cooccurrences, memory_links with entity_id) + cursor.execute("DELETE FROM entities WHERE agent_id = %s", (agent_id,)) self.conn.commit() - # Step 4: Sort by final weight and return top results - results.sort(key=lambda x: x["weight"], reverse=True) - return results[:top_k] + return { + "memory_units_deleted": units_count, + "entities_deleted": entities_count + } except Exception as e: self.conn.rollback() - raise Exception(f"Failed to search memories: {str(e)}") + raise Exception(f"Failed to delete agent data: {str(e)}") finally: cursor.close() @@ -743,76 +958,145 @@ class TemporalSemanticMemory: finally: cursor.close() - def _extract_entities_for_batch( + def _extract_entities_batch_optimized( self, cursor, agent_id: str, - unit_id: str, - text: str, + unit_ids: List[str], + sentences: List[str], context: str, - event_date, - all_sentences: List[str], + fact_dates: List, ) -> List[tuple]: """ - Extract entities and return entity links (doesn't insert yet). + Extract entities from ALL sentences in one batch (MUCH faster than sequential). + + Uses spaCy's batch processing to extract entities from all texts at once, + then resolves and links them in bulk. Returns list of tuples for batch insertion: (from_unit_id, to_unit_id, link_type, weight, entity_id) """ - from .entity_resolver import extract_entities + from .entity_resolver import extract_entities_batch try: - # Extract entities from this unit - entities = extract_entities(text) + # Step 1: Extract entities from ALL sentences in one batch (fast!) + substep_start = time.time() + all_entities = extract_entities_batch(sentences) + total_entities = sum(len(ents) for ents in all_entities) + print(f" [6.1] spaCy NER (batch): {total_entities} entities from {len(sentences)} sentences in {time.time() - substep_start:.3f}s") - if not entities: - return [] + # Step 2: Resolve entities in BATCH (much faster!) + substep_start = time.time() + step_6_2_start = time.time() - # Resolve each entity - entity_ids = [] - for entity in entities: - entity_id = self.entity_resolver.resolve_entity( - agent_id=agent_id, - entity_text=entity['text'], - entity_type=entity['type'], - context=context, - nearby_entities=entities, - unit_event_date=event_date - ) - entity_ids.append(entity_id) + # [6.2.1] Prepare all entities for batch resolution + substep_6_2_1_start = time.time() + all_entities_flat = [] + entity_to_unit = [] # Maps flat index to (unit_id, local_index) - # Link unit to entity (this inserts into entity_units) - self.entity_resolver.link_unit_to_entity(unit_id, entity_id) + for unit_id, entities, fact_date in zip(unit_ids, all_entities, fact_dates): + if not entities: + continue - # Now collect entity links for batch insertion - # After link_unit_to_entity has been called, entity_units should exist - links = [] - for entity_id in set(entity_ids): - # Find all other units with this entity (cursor must be fresh) - try: - cursor.execute( - """ - SELECT unit_id - FROM unit_entities - WHERE entity_id = %s AND unit_id != %s - """, - (entity_id, unit_id) + for local_idx, entity in enumerate(entities): + all_entities_flat.append({ + 'text': entity['text'], + 'type': entity['type'], + 'nearby_entities': entities, + }) + entity_to_unit.append((unit_id, local_idx, fact_date)) + print(f" [6.2.1] Prepare entities: {len(all_entities_flat)} entities in {time.time() - substep_6_2_1_start:.3f}s") + + # Resolve ALL entities in one batch call + if all_entities_flat: + # [6.2.2] Batch resolve entities + substep_6_2_2_start = time.time() + # Group by date for batch resolution (most will have same date) + entities_by_date = {} + for idx, (unit_id, local_idx, fact_date) in enumerate(entity_to_unit): + date_key = fact_date + if date_key not in entities_by_date: + entities_by_date[date_key] = [] + entities_by_date[date_key].append((idx, all_entities_flat[idx])) + + # Resolve each date group in batch + resolved_entity_ids = [None] * len(all_entities_flat) + for fact_date, entities_group in entities_by_date.items(): + indices = [idx for idx, _ in entities_group] + entities_data = [entity_data for _, entity_data in entities_group] + + batch_resolved = self.entity_resolver.resolve_entities_batch( + agent_id=agent_id, + entities_data=entities_data, + context=context, + unit_event_date=fact_date ) - related_units = cursor.fetchall() - for (related_unit_id,) in related_units: + for idx, entity_id in zip(indices, batch_resolved): + resolved_entity_ids[idx] = entity_id + print(f" [6.2.2] Resolve entities: {len(all_entities_flat)} entities in {time.time() - substep_6_2_2_start:.3f}s") + + # [6.2.3] Create unit-entity links in BATCH + substep_6_2_3_start = time.time() + # Map resolved entities back to units and collect all (unit, entity) pairs + unit_to_entity_ids = {} + unit_entity_pairs = [] + for idx, (unit_id, local_idx, fact_date) in enumerate(entity_to_unit): + if unit_id not in unit_to_entity_ids: + unit_to_entity_ids[unit_id] = [] + + entity_id = resolved_entity_ids[idx] + unit_to_entity_ids[unit_id].append(entity_id) + unit_entity_pairs.append((unit_id, entity_id)) + + # Batch insert all unit-entity links (MUCH faster!) + self.entity_resolver.link_units_to_entities_batch(unit_entity_pairs) + print(f" [6.2.3] Create unit-entity links (batched): {len(unit_entity_pairs)} links in {time.time() - substep_6_2_3_start:.3f}s") + + print(f" [6.2] Entity resolution (batched): {len(all_entities_flat)} entities resolved in {time.time() - step_6_2_start:.3f}s") + else: + unit_to_entity_ids = {} + print(f" [6.2] Entity resolution (batched): 0 entities in {time.time() - step_6_2_start:.3f}s") + + # Step 3: Create entity links between units that share entities + substep_start = time.time() + # Collect all unique entity IDs + all_entity_ids = set() + for entity_ids in unit_to_entity_ids.values(): + all_entity_ids.update(entity_ids) + + # For each entity, find all units that reference it (one query per entity) + entity_to_units = {} + for entity_id in all_entity_ids: + cursor.execute( + """ + SELECT unit_id + FROM unit_entities + WHERE entity_id = %s + """, + (entity_id,) + ) + entity_to_units[entity_id] = [row[0] for row in cursor.fetchall()] + + # Create bidirectional links between units that share entities + links = [] + for entity_id, units_with_entity in entity_to_units.items(): + # For each pair of units with this entity, create bidirectional links + for i, unit_id_1 in enumerate(units_with_entity): + for unit_id_2 in units_with_entity[i+1:]: # Bidirectional links - links.append((unit_id, related_unit_id, 'entity', 1.0, entity_id)) - links.append((related_unit_id, unit_id, 'entity', 1.0, entity_id)) - except Exception as query_error: - # If there's an error querying, just skip this entity - print(f"Warning: Failed to query entity_units for {entity_id}: {str(query_error)}") - continue + links.append((unit_id_1, unit_id_2, 'entity', 1.0, entity_id)) + links.append((unit_id_2, unit_id_1, 'entity', 1.0, entity_id)) + + print(f" [6.3] Entity link creation: {len(links)} links for {len(all_entity_ids)} unique entities in {time.time() - substep_start:.3f}s") return links except Exception as e: - print(f"Warning: Failed to extract entities: {str(e)}") - return [] + print(f"ERROR: Failed to extract entities in batch: {str(e)}") + import traceback + traceback.print_exc() + # Re-raise to trigger rollback at put_async level + raise def _create_temporal_links_batch( self, @@ -870,7 +1154,89 @@ class TemporalSemanticMemory: ) except Exception as e: - print(f"Warning: Failed to create temporal links: {str(e)}") + print(f"ERROR: Failed to create temporal links: {str(e)}") + import traceback + traceback.print_exc() + # Re-raise to trigger rollback at put_async level + raise + + def _create_temporal_links_batch_per_fact( + self, + cursor, + agent_id: str, + unit_ids: List[str], + time_window_hours: int = 24, + ): + """ + Create temporal links for multiple units, each with their own event_date. + + Queries the event_date for each unit from the database and creates temporal + links based on individual dates (supports per-fact dating). + """ + if not unit_ids: + return + + try: + from psycopg2.extras import execute_values + + # Get the event_date for each new unit + cursor.execute( + """ + SELECT id, event_date + FROM memory_units + WHERE id::text = ANY(%s) + """, + (unit_ids,) + ) + new_units = {str(row[0]): row[1] for row in cursor.fetchall()} + + # Create links based on each unit's individual event_date + links = [] + for unit_id, unit_event_date in new_units.items(): + # Find units within the time window of THIS specific unit + cursor.execute( + """ + SELECT id, event_date + FROM memory_units + WHERE agent_id = %s + AND id != %s + AND event_date BETWEEN %s AND %s + ORDER BY event_date DESC + LIMIT 10 + """, + ( + agent_id, + unit_id, + unit_event_date - timedelta(hours=time_window_hours), + unit_event_date + timedelta(hours=time_window_hours) + ) + ) + + recent_units = cursor.fetchall() + + for recent_id, recent_event_date in recent_units: + # Calculate temporal proximity weight + time_diff_hours = abs((unit_event_date - recent_event_date).total_seconds() / 3600) + weight = max(0.3, 1.0 - (time_diff_hours / time_window_hours)) + links.append((unit_id, recent_id, 'temporal', weight, None)) + + if links: + execute_values( + cursor, + """ + INSERT INTO memory_links (from_unit_id, to_unit_id, link_type, weight, entity_id) + VALUES %s + ON CONFLICT (from_unit_id, to_unit_id, link_type, COALESCE(entity_id, '00000000-0000-0000-0000-000000000000'::uuid)) DO NOTHING + """, + links + ) + + except Exception as e: + print(f"ERROR: Failed to create temporal links: {str(e)}") + import traceback + traceback.print_exc() + # Re-raise to trigger rollback at put_async level + raise def _create_semantic_links_batch( self, @@ -927,7 +1293,11 @@ class TemporalSemanticMemory: ) except Exception as e: - print(f"Warning: Failed to create semantic links: {str(e)}") + print(f"ERROR: Failed to create semantic links: {str(e)}") + import traceback + traceback.print_exc() + # Re-raise to trigger rollback at put_async level + raise def _insert_entity_links_batch(self, cursor, links: List[tuple]): """Insert all entity links in a single batch.""" diff --git a/memory/utils.py b/memory/utils.py index 0593cec9..d7bb6126 100644 --- a/memory/utils.py +++ b/memory/utils.py @@ -1,24 +1,28 @@ """ Utility functions for memory system. """ -from typing import List +from datetime import datetime +from typing import List, Dict from .llm_client import extract_facts_from_text -async def extract_facts(text: str) -> List[str]: +async def extract_facts(text: str, event_date: datetime, context: str = "") -> List[Dict[str, str]]: """ Extract semantic facts from text using LLM. Uses LLM for intelligent fact extraction that: - Filters out social pleasantries and filler words - - Creates self-contained statements + - Creates self-contained statements with absolute dates - Handles conversational text well + - Resolves relative time expressions to absolute dates Args: text: Input text (conversation, article, etc.) + event_date: Reference date for resolving relative times + context: Context about the conversation/document Returns: - List of factual statements + List of fact dictionaries with keys: 'fact' (text) and 'date' (ISO string) Raises: Exception: If LLM fact extraction fails @@ -26,14 +30,12 @@ async def extract_facts(text: str) -> List[str]: if not text or not text.strip(): return [] - fact_dicts = await extract_facts_from_text(text) - # Extract just the fact text - facts = [f['fact'] for f in fact_dicts if f.get('fact')] + fact_dicts = await extract_facts_from_text(text, event_date, context) - if not facts: + if not fact_dicts: raise Exception(f"LLM extracted 0 facts from text of length {len(text)}. This may indicate the text contains no meaningful information, or the LLM failed to extract facts.") - return facts + return fact_dicts def cosine_similarity(vec1: List[float], vec2: List[float]) -> float: diff --git a/memory_graph_interactive.html b/memory_graph_interactive.html index ee7948df..94031fd3 100644 --- a/memory_graph_interactive.html +++ b/memory_graph_interactive.html @@ -1,181 +1,423 @@ + + - - - - - - - - -
-

Entity-Aware Memory Graph - Interactive Visualization

-
+ + Memory Graph - Interactive Visualization + + + - + .tab-content.active { + display: block; + } + #cy { + width: 100%; + height: 800px; + background: #ffffff; + } - -
-

Legend

+ #graph-tab { + position: relative; + } -

Link Types:

-
-
- - Temporal - Time-based (cyan, dashed) + #table-tab { + padding: 20px; + } + + .legend { + position: absolute; + top: 20px; + left: 20px; + background: white; + padding: 15px; + border: 2px solid #333; + border-radius: 8px; + box-shadow: 2px 2px 8px rgba(0,0,0,0.3); + z-index: 1000; + max-width: 250px; + } + + .legend h3 { + margin-top: 0; + border-bottom: 2px solid #333; + padding-bottom: 5px; + } + + .legend-item { + margin: 8px 0; + display: flex; + align-items: center; + } + + .legend-line { + width: 30px; + height: 2px; + margin-right: 10px; + } + + .legend-node { + width: 20px; + height: 20px; + margin-right: 10px; + border: 1px solid #999; + border-radius: 3px; + } + + #table-filter { + width: 100%; + max-width: 600px; + padding: 10px; + margin-bottom: 15px; + border: 2px solid #ccc; + border-radius: 4px; + font-size: 14px; + box-sizing: border-box; + } + + #memory-table { + width: 100%; + border-collapse: collapse; + font-size: 13px; + max-width: 1400px; + } + + #memory-table th { + padding: 10px; + text-align: left; + border: 1px solid #ddd; + background: #f0f0f0; + } + + #memory-table td { + padding: 8px; + border: 1px solid #ddd; + } + + .tooltip { + position: absolute; + background: white; + border: 2px solid #333; + border-radius: 4px; + padding: 10px; + box-shadow: 2px 2px 8px rgba(0,0,0,0.3); + max-width: 300px; + font-size: 12px; + pointer-events: none; + z-index: 9999; + } + + + +
+
+ + +
+ +
+
+
+
+ + +
+
+ + +
+ + +
-
- - Semantic - Meaning-based (pink, solid) -
-
- - Entity - Same entity (gold, thick) +
+
+

Legend

+

Link Types:

+
+
+ Temporal +
+
+
+ Semantic +
+
+
+ Entity +
+

Nodes:

+
+
+ No entities +
+
+
+ 1 entity +
+
+
+ 2+ entities +
-

Node Colors:

-
-
- - Gray - No entities +
+

Memory Units (0)

+ +
+ + + + + + + + + + + + + +
IDTextContextDateEntities
-
- - Light Blue - 1 entity -
-
- - Dark Blue - 2+ entities -
-
- -
- Tip: Hover over nodes/edges for details
- Controls: Drag to move, scroll to zoom
- -
- - -
-
- - + - - \ No newline at end of file + rows.forEach(row => { + const text = row.textContent.toLowerCase(); + if (text.includes(filterValue)) { + row.style.display = ''; + } else { + row.style.display = 'none'; + } + }); + }); + + + diff --git a/pyproject.toml b/pyproject.toml index 1a80c2ca..4cfebc68 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,10 +15,9 @@ dependencies = [ "matplotlib>=3.7.0", "rich>=13.0.0", "spacy>=3.7.0", - "pyvis>=0.3.0", "sentence-transformers>=2.2.0", "torch>=2.0.0", "pytest>=7.0.0", "pytest-asyncio>=0.21.0", - "fastcoref>=2.1.0", + "langchain-text-splitters>=0.3.0", ] diff --git a/tests/conftest.py b/tests/conftest.py index 242a3ec8..ab5c4576 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,10 +2,10 @@ Pytest configuration and shared fixtures. """ import pytest -import psycopg2 import os from dotenv import load_dotenv from memory import TemporalSemanticMemory +import psycopg2 load_dotenv() @@ -24,28 +24,17 @@ def memory(): def clean_agent(memory): """ Provide a clean agent ID and clean up data after test. + Uses agent_id='test' for all tests (multi-tenant isolation). """ - agent_id = "test_agent" + agent_id = "test" # Clean up before test - conn = psycopg2.connect(os.getenv('DATABASE_URL')) - cursor = conn.cursor() - cursor.execute("DELETE FROM memory_units WHERE agent_id = %s", (agent_id,)) - cursor.execute("DELETE FROM entities WHERE agent_id = %s", (agent_id,)) - conn.commit() - cursor.close() - conn.close() + memory.delete_agent(agent_id) yield agent_id # Clean up after test - conn = psycopg2.connect(os.getenv('DATABASE_URL')) - cursor = conn.cursor() - cursor.execute("DELETE FROM memory_units WHERE agent_id = %s", (agent_id,)) - cursor.execute("DELETE FROM entities WHERE agent_id = %s", (agent_id,)) - conn.commit() - cursor.close() - conn.close() + memory.delete_agent(agent_id) @pytest.fixture diff --git a/tests/test_chunking.py b/tests/test_chunking.py index b6255551..3ebc973c 100644 --- a/tests/test_chunking.py +++ b/tests/test_chunking.py @@ -2,19 +2,7 @@ Test chunking functionality for large documents. """ import pytest -from memory.llm_client import chunk_text, split_into_sentences - - -def test_split_into_sentences(): - """Test sentence splitting.""" - text = "This is sentence one. This is sentence two! Is this sentence three? Yes it is." - sentences = split_into_sentences(text) - - assert len(sentences) == 4, f"Expected 4 sentences, got {len(sentences)}" - assert "This is sentence one" in sentences[0] - assert "This is sentence two" in sentences[1] - assert "Is this sentence three" in sentences[2] - assert "Yes it is" in sentences[3] +from memory.llm_client import chunk_text def test_chunk_text_small(): diff --git a/tests/test_coref_performance.py b/tests/test_coref_performance.py deleted file mode 100644 index 97c36de6..00000000 --- a/tests/test_coref_performance.py +++ /dev/null @@ -1,57 +0,0 @@ -""" -Performance test for coreference resolution. -""" -import time -from memory.coref_resolver import resolve_sentences, resolve_sentences_fast, resolve_sentences_legacy - - -def test_coref_performance(): - """Compare performance of fast vs legacy coreference resolution.""" - - # Sample sentences with coreferences - test_sentences = [ - "John is a software engineer.", - "He works at a tech company.", - "The company is based in San Francisco.", - "He enjoys working on AI projects.", - "The projects involve machine learning.", - "John believes AI will transform the industry.", - "He has been working on this for 5 years.", - "The experience has been valuable.", - "John plans to continue his research.", - "He is passionate about the field.", - ] * 10 # Repeat 10 times to make it 100 sentences - - print(f"\nTesting with {len(test_sentences)} sentences...") - - # Test fast method - start = time.time() - resolved_fast = resolve_sentences_fast(test_sentences) - fast_time = time.time() - start - print(f"FastCoref: {fast_time:.3f} seconds") - - # Test legacy method (with smaller dataset to avoid timeout) - small_test = test_sentences[:20] - start = time.time() - resolved_legacy = resolve_sentences_legacy(small_test) - legacy_time = time.time() - start - print(f"Legacy (20 sentences): {legacy_time:.3f} seconds") - - # Extrapolate legacy time - extrapolated_legacy = legacy_time * (len(test_sentences) / len(small_test)) ** 2 - print(f"Legacy (extrapolated for {len(test_sentences)}): {extrapolated_legacy:.3f} seconds") - - speedup = extrapolated_legacy / fast_time if fast_time > 0 else float('inf') - print(f"Speedup: {speedup:.1f}x faster") - - # Verify resolution worked - print("\nSample resolved sentences (FastCoref):") - for i, sent in enumerate(resolved_fast[:3]): - print(f" {i+1}. {sent}") - - assert len(resolved_fast) == len(test_sentences) - assert fast_time < extrapolated_legacy - - -if __name__ == "__main__": - test_coref_performance() diff --git a/tests/test_deduplication.py b/tests/test_deduplication.py deleted file mode 100644 index 79586f6b..00000000 --- a/tests/test_deduplication.py +++ /dev/null @@ -1,111 +0,0 @@ -""" -Test deduplication of identical puts. -""" -import pytest -from datetime import datetime, timezone -from memory.temporal_semantic_memory import TemporalSemanticMemory - - -@pytest.fixture -def memory(): - """Create a memory instance for testing.""" - mem = TemporalSemanticMemory() - yield mem - # Cleanup after test - cursor = mem.conn.cursor() - cursor.execute("DELETE FROM memory_units WHERE agent_id LIKE 'test_%'") - mem.conn.commit() - cursor.close() - - -@pytest.mark.asyncio -async def test_duplicate_put_filters_identical_content(memory): - """Test that putting the same content twice doesn't create duplicates.""" - - agent_id = "test_dedup_agent" - content = "Alice works at Google as a software engineer. She joined last year and loves Python." - event_date = datetime(2024, 1, 15, 10, 0, 0, tzinfo=timezone.utc) - - # First put - should create units - print("\n--- FIRST PUT ---") - units_1 = await memory.put_async(agent_id, content, "Test context", event_date) - - assert len(units_1) > 0, "First put should create units" - print(f"First put created {len(units_1)} units") - - # Second put with identical content and same date - should be filtered as duplicates - print("\n--- SECOND PUT (identical) ---") - units_2 = await memory.put_async(agent_id, content, "Test context", event_date) - - assert len(units_2) == 0, "Second identical put should create no new units (all duplicates)" - print(f"Second put created {len(units_2)} units (expected 0)") - - # Verify database has only the first set of units - cursor = memory.conn.cursor() - cursor.execute( - "SELECT COUNT(*) FROM memory_units WHERE agent_id = %s", - (agent_id,) - ) - total_units = cursor.fetchone()[0] - cursor.close() - - assert total_units == len(units_1), f"Database should have {len(units_1)} units, found {total_units}" - print(f"✅ Deduplication working: {total_units} total units in database") - - -@pytest.mark.asyncio -async def test_duplicate_put_with_paraphrased_content(memory): - """Test that similar but paraphrased content is also deduplicated.""" - - agent_id = "test_paraphrase_agent" - event_date = datetime(2024, 1, 15, 10, 0, 0, tzinfo=timezone.utc) - - # First put - content_1 = "Bob is a chef in New York. He owns a restaurant." - print("\n--- FIRST PUT ---") - units_1 = await memory.put_async(agent_id, content_1, "Test", event_date) - - assert len(units_1) > 0, "First put should create units" - print(f"First put created {len(units_1)} units") - - # Second put with paraphrased content - should be mostly deduplicated - # The LLM will extract similar facts that should match via embeddings - content_2 = "Bob works as a chef in New York City. He is the owner of a restaurant." - print("\n--- SECOND PUT (paraphrased) ---") - units_2 = await memory.put_async(agent_id, content_2, "Test", event_date) - - # May create 0 or very few new units (depending on how LLM extracts facts) - print(f"Second put created {len(units_2)} units") - print(f"Deduplication ratio: {len(units_2)}/{len(units_1)} new units from paraphrase") - - # Just verify it doesn't create the same number of units (some deduplication should happen) - assert len(units_2) < len(units_1), "Paraphrased content should have fewer new units due to deduplication" - - -@pytest.mark.asyncio -async def test_different_dates_not_deduplicated(memory): - """Test that same content with different dates is NOT deduplicated.""" - - agent_id = "test_dates_agent" - content = "Charlie went hiking in Yosemite." - - # First put at date 1 - date_1 = datetime(2024, 1, 1, 10, 0, 0, tzinfo=timezone.utc) - print("\n--- FIRST PUT (Jan 1) ---") - units_1 = await memory.put_async(agent_id, content, "Test", date_1) - - assert len(units_1) > 0 - print(f"First put created {len(units_1)} units") - - # Second put at date 2 (outside 24-hour window) - date_2 = datetime(2024, 2, 1, 10, 0, 0, tzinfo=timezone.utc) - print("\n--- SECOND PUT (Feb 1, outside time window) ---") - units_2 = await memory.put_async(agent_id, content, "Test", date_2) - - # Should create new units because dates are far apart - assert len(units_2) > 0, "Same content with different dates (outside window) should create new units" - print(f"Second put created {len(units_2)} units (not deduplicated due to date difference)") - - -if __name__ == "__main__": - pytest.main([__file__, "-v", "-s"]) diff --git a/tests/test_detailed_extraction.py b/tests/test_detailed_extraction.py deleted file mode 100644 index a38c82d2..00000000 --- a/tests/test_detailed_extraction.py +++ /dev/null @@ -1,107 +0,0 @@ -""" -Test that the improved prompt extracts detailed, comprehensive facts. -""" -import pytest -from memory.llm_client import extract_facts_from_text - - -@pytest.mark.asyncio -async def test_detailed_extraction_preserves_context(): - """Test that facts preserve all context and details.""" - - text = """ - Alice mentioned she works at Google in Mountain View on the AI research team. - She joined last year after finishing her PhD at Stanford, and she's currently - focused on improving large language model safety through red teaming and - adversarial testing. She said the work is challenging but very rewarding because - it directly impacts millions of users. - """ - - facts = await extract_facts_from_text(text) - - print(f"\nExtracted {len(facts)} facts:") - for i, fact in enumerate(facts, 1): - print(f"{i}. {fact['fact']}") - print(f" Type: {fact['type']}, Speaker: {fact['speaker']}, Confidence: {fact['confidence']}\n") - - # Verify we got facts - assert len(facts) > 0, "Should extract at least one fact" - - # Check that facts contain detailed information - fact_texts = [f['fact'].lower() for f in facts] - combined_facts = ' '.join(fact_texts) - - # Should preserve location details - assert 'mountain view' in combined_facts, "Should preserve specific location 'Mountain View'" - - # Should preserve team/department - assert 'ai' in combined_facts or 'research' in combined_facts, "Should preserve team information" - - # Should preserve educational background - assert 'stanford' in combined_facts or 'phd' in combined_facts, "Should preserve educational background" - - # Should preserve work details - assert 'safety' in combined_facts or 'red teaming' in combined_facts or 'adversarial' in combined_facts, \ - "Should preserve specific work focus details" - - # Check that at least one fact is reasonably detailed (not just "Alice works at Google") - detailed_fact_found = any(len(f['fact'].split()) >= 10 for f in facts) - assert detailed_fact_found, "At least one fact should be detailed (10+ words)" - - -@pytest.mark.asyncio -async def test_numbers_and_metrics_preserved(): - """Test that numbers, percentages, and metrics are preserved.""" - - text = """ - Bob explained that the new caching algorithm reduced API latency by 40% - compared to the baseline, processing 10,000 requests per second instead - of the previous 7,000. This improvement was achieved by implementing a - two-tier LRU cache with 1GB memory allocation. - """ - - facts = await extract_facts_from_text(text) - - print(f"\nExtracted {len(facts)} facts:") - for fact in facts: - print(f"- {fact['fact']}") - - combined = ' '.join([f['fact'] for f in facts]) - - # Should preserve specific numbers - assert '40' in combined or 'forty' in combined.lower(), "Should preserve percentage" - assert '10,000' in combined or '10000' in combined or 'ten thousand' in combined.lower(), \ - "Should preserve request rate" - assert 'cache' in combined.lower(), "Should preserve technical details" - - -@pytest.mark.asyncio -async def test_reasons_and_causality_preserved(): - """Test that reasons, causes, and explanations are preserved.""" - - text = """ - Sarah has been meditating every morning for the past 6 months because - she found it significantly reduced her anxiety levels and improved her - focus during work hours. She started this practice after reading a research - paper on mindfulness benefits. - """ - - facts = await extract_facts_from_text(text) - - print(f"\nExtracted {len(facts)} facts:") - for fact in facts: - print(f"- {fact['fact']}") - - combined = ' '.join([f['fact'] for f in facts]) - - # Should preserve the causal relationship (because/reason) - assert any(keyword in combined.lower() for keyword in ['because', 'reduced', 'anxiety', 'improved']), \ - "Should preserve the reason/causality" - - # Should preserve frequency - assert 'morning' in combined.lower() or 'every' in combined.lower(), \ - "Should preserve frequency information" - - -if __name__ == "__main__": - pytest.main([__file__, "-v", "-s"]) diff --git a/tests/test_entity_linking.py b/tests/test_entity_linking.py deleted file mode 100644 index 38f3a285..00000000 --- a/tests/test_entity_linking.py +++ /dev/null @@ -1,212 +0,0 @@ -""" -Test entity-aware memory linking functionality. - -Tests that entity resolution connects memories about the same person/place/thing. -""" -import pytest -from datetime import datetime, timedelta, timezone - - -def utcnow(): - """Get current UTC time with timezone info.""" - return datetime.now(timezone.utc) - - -def test_entity_extraction_and_linking(memory, clean_agent, db_connection): - """Test that entities are extracted and linked correctly.""" - agent_id = clean_agent - - # Store memories about Alice's hiking hobby - memory.put( - agent_id=agent_id, - content="Alice told me she loves hiking in the mountains. " - "She goes hiking every weekend in Yosemite.", - context="Casual conversation about hobbies", - event_date=utcnow() - timedelta(days=7), - ) - - # Store memories about Alice's work (different context!) - memory.put( - agent_id=agent_id, - content="Alice works at Google as a software engineer. " - "She joined Google last year and loves the culture.", - context="Discussion about careers", - event_date=utcnow() - timedelta(days=3), - ) - - # Store more about hiking (no Alice mention) - memory.put( - agent_id=agent_id, - content="Bob mentioned he enjoys rock climbing. " - "He climbs in Yosemite too, on weekends.", - context="Outdoor activities discussion", - event_date=utcnow() - timedelta(days=1), - ) - - # Store another Alice memory - memory.put( - agent_id=agent_id, - content="Alice is working on a Python project at Google. " - "The project uses machine learning.", - context="Technical discussion", - event_date=utcnow(), - ) - - # Verify entities were extracted - cursor = db_connection.cursor() - cursor.execute(""" - SELECT canonical_name, entity_type, mention_count - FROM entities - WHERE agent_id = %s - ORDER BY mention_count DESC - """, (agent_id,)) - - entities = cursor.fetchall() - entity_names = [e[0] for e in entities] - - # Should have Alice, Google, Yosemite, Bob - assert "Alice" in entity_names, "Alice entity should be extracted" - assert "Google" in entity_names, "Google entity should be extracted" - assert "Yosemite" in entity_names, "Yosemite entity should be extracted" - assert "Bob" in entity_names, "Bob entity should be extracted" - - # Alice should have multiple mentions - alice_entity = next((e for e in entities if e[0] == "Alice"), None) - assert alice_entity is not None - assert alice_entity[2] >= 3, "Alice should have at least 3 mentions" - - # Verify entity links exist - cursor.execute(""" - SELECT COUNT(*) - FROM memory_links - WHERE link_type = 'entity' - AND from_unit_id IN ( - SELECT id FROM memory_units WHERE agent_id = %s - ) - """, (agent_id,)) - - entity_link_count = cursor.fetchone()[0] - assert entity_link_count > 0, "Entity links should be created" - - cursor.close() - - -def test_entity_search_retrieves_all_related_memories(memory, clean_agent): - """Test that searching for an entity retrieves ALL memories about that entity.""" - agent_id = clean_agent - - # Store diverse memories about Alice - memory.put( - agent_id=agent_id, - content="Alice loves hiking in the mountains.", - context="Hobbies", - event_date=utcnow() - timedelta(days=7), - ) - - memory.put( - agent_id=agent_id, - content="Alice works at Google as a software engineer.", - context="Career", - event_date=utcnow() - timedelta(days=3), - ) - - memory.put( - agent_id=agent_id, - content="Alice is working on a Python machine learning project.", - context="Technical", - event_date=utcnow(), - ) - - # Query about Alice - should get ALL Alice memories via entity links - results = memory.search( - agent_id=agent_id, - query="What does Alice do?", - thinking_budget=30, - top_k=10, - ) - - # Should retrieve multiple memories about Alice - assert len(results) >= 2, "Should find multiple memories about Alice" - - # Check that results contain Alice-related content - alice_mentions = sum(1 for r in results if "Alice" in r['text']) - assert alice_mentions >= 2, "Multiple results should mention Alice" - - -def test_entity_disambiguation(memory, clean_agent, db_connection): - """Test that entity disambiguation correctly identifies same vs different entities.""" - agent_id = clean_agent - - # Store two memories about "Alice" in different contexts - memory.put( - agent_id=agent_id, - content="Alice from engineering loves Python.", - context="Tech team", - event_date=utcnow() - timedelta(days=2), - ) - - memory.put( - agent_id=agent_id, - content="Alice from engineering is working on a new project.", - context="Tech team", - event_date=utcnow(), - ) - - # Check that only ONE Alice entity was created (not two) - cursor = db_connection.cursor() - cursor.execute(""" - SELECT COUNT(*) - FROM entities - WHERE agent_id = %s AND canonical_name = 'Alice' - """, (agent_id,)) - - alice_count = cursor.fetchone()[0] - assert alice_count == 1, "Should create only one Alice entity (disambiguation)" - - cursor.close() - - -def test_link_type_distribution(memory, clean_agent, db_connection): - """Test that all three link types (temporal, semantic, entity) are created.""" - agent_id = clean_agent - - # Store related memories - memory.put( - agent_id=agent_id, - content="Alice works at Google. She loves her job.", - context="Career", - event_date=utcnow() - timedelta(hours=2), - ) - - memory.put( - agent_id=agent_id, - content="Bob also works at Google. He is in sales.", - context="Career", - event_date=utcnow() - timedelta(hours=1), - ) - - memory.put( - agent_id=agent_id, - content="Google is a great company to work for.", - context="Career", - event_date=utcnow(), - ) - - # Check link types - cursor = db_connection.cursor() - cursor.execute(""" - SELECT link_type, COUNT(*) as count - FROM memory_links ml - JOIN memory_units mu ON ml.from_unit_id = mu.id - WHERE mu.agent_id = %s - GROUP BY link_type - ORDER BY count DESC - """, (agent_id,)) - - link_types = {row[0]: row[1] for row in cursor.fetchall()} - - # Should have at least temporal and entity links (semantic depends on similarity threshold) - assert 'temporal' in link_types, "Should create temporal links" - assert 'entity' in link_types or 'semantic' in link_types, "Should create entity or semantic links" - - cursor.close() diff --git a/tests/test_fact_extraction.py b/tests/test_fact_extraction.py deleted file mode 100644 index ea0c28fc..00000000 --- a/tests/test_fact_extraction.py +++ /dev/null @@ -1,130 +0,0 @@ -""" -Test LLM-based fact extraction. -""" -import pytest -from memory.llm_client import extract_facts_from_text -from memory.utils import extract_facts - - -async def test_fact_extraction_filters_pleasantries(): - """Test that fact extraction filters out social pleasantries.""" - - conversation = """ - Host: Welcome to the show, Marta! Thanks for joining us. - Marta: Oh, thank you so much for having me! - Host: So tell us, what do you do? - Marta: I work at Google as a software engineer. I've been there for 3 years now. - Host: That's amazing! - Marta: Yeah, I really enjoy it. I mostly work on AI infrastructure. - Host: Uh-huh, interesting. - Marta: And I'm also passionate about hiking. I go to Yosemite almost every weekend. - Host: Wow, that sounds great! - """ - - facts = await extract_facts_from_text(conversation) - - # Extract just the fact texts - fact_texts = [f['fact'].lower() for f in facts] - - print("\nExtracted facts:") - for fact in facts: - print(f" - {fact['fact']} (speaker: {fact['speaker']}, type: {fact['type']})") - - # Should extract meaningful facts - assert any('google' in fact and 'software engineer' in fact for fact in fact_texts), \ - "Should extract Marta's job at Google" - assert any('yosemite' in fact and 'hiking' in fact for fact in fact_texts), \ - "Should extract Marta's hiking hobby" - - # Should NOT extract pleasantries - assert not any('thank you' in fact for fact in fact_texts), \ - "Should not extract 'thank you'" - assert not any('amazing' in fact and len(fact.split()) < 5 for fact in fact_texts), \ - "Should not extract simple reactions like 'that's amazing'" - assert not any('uh-huh' in fact for fact in fact_texts), \ - "Should not extract acknowledgments" - - -async def test_fact_extraction_makes_self_contained(): - """Test that facts are self-contained (pronouns resolved).""" - - conversation = """ - Alice told me she works at Microsoft. - She mentioned that she's been there for 5 years. - She really enjoys her team. - """ - - facts = await extract_facts_from_text(conversation) - - print("\nExtracted facts:") - for fact in facts: - print(f" - {fact['fact']}") - - # All facts should mention "Alice" explicitly, not "she" - for fact in facts: - fact_text = fact['fact'].lower() - # If it's about Alice, it should say "alice" not "she" - if 'microsoft' in fact_text or 'team' in fact_text: - assert 'alice' in fact_text, \ - f"Fact should be self-contained with 'Alice', not pronouns: {fact['fact']}" - - -async def test_extract_facts_util_function(): - """Test the utils.extract_facts() wrapper function.""" - - text = """ - Bob is a chef in New York. He owns a restaurant called "The Kitchen". - Thank you! Yeah, uh-huh. - """ - - facts = await extract_facts(text) - - print("\nExtracted facts:") - for fact in facts: - print(f" - {fact}") - - assert len(facts) > 0, "Should extract at least one fact" - assert any('bob' in fact.lower() and 'chef' in fact.lower() for fact in facts), \ - "Should extract Bob's profession" - assert not any('thank you' in fact.lower() for fact in facts), \ - "Should filter out pleasantries" - - -async def test_extract_facts_basic(): - """Test basic fact extraction.""" - - text = "Alice works at Google. She loves Python programming." - - facts = await extract_facts(text) - - assert len(facts) > 0, "Should extract at least one fact" - assert any('alice' in fact.lower() for fact in facts), "Should extract facts about Alice" - - -if __name__ == "__main__": - import asyncio - - # Run a manual test - async def main(): - conversation = """ - Host: Welcome to the AI podcast! Today we have Dr. Sarah Chen with us. - Sarah: Hi! Thanks for having me. - Host: So Sarah, tell us about your work. - Sarah: I'm a researcher at Stanford focusing on large language models. - Host: Oh wow! - Sarah: Yeah, I've been studying how LLMs handle reasoning tasks. It's fascinating. - Sarah: We published a paper last month showing that chain-of-thought prompting improves accuracy by 40%. - Host: That's incredible! - Sarah: And I'm also advising a startup called MemoryAI that's building long-term memory systems. - Host: Cool, cool. - """ - - print("Testing fact extraction with podcast conversation:") - print("=" * 60) - facts = await extract_facts_from_text(conversation) - print(f"\nExtracted {len(facts)} facts:\n") - for i, fact in enumerate(facts, 1): - print(f"{i}. {fact['fact']}") - print(f" Speaker: {fact['speaker']}, Type: {fact['type']}, Confidence: {fact['confidence']}\n") - - asyncio.run(main()) diff --git a/tests/test_memory_operations.py b/tests/test_memory_operations.py deleted file mode 100644 index 2fd76716..00000000 --- a/tests/test_memory_operations.py +++ /dev/null @@ -1,223 +0,0 @@ -""" -Test basic memory operations: PUT, SEARCH, GET_RECENT. - -Tests the core functionality of the temporal + semantic memory system. -""" -import pytest -import asyncio -from datetime import datetime, timedelta, timezone - - -def utcnow(): - """Get current UTC time with timezone info.""" - return datetime.now(timezone.utc) - - -@pytest.mark.asyncio -async def test_put_creates_memory_units(memory, clean_agent, db_connection): - """Test that PUT operation creates memory units.""" - agent_id = clean_agent - - # Store a conversation - await memory.put_async( - agent_id=agent_id, - content="Alice told me she loves hiking in the mountains. " - "She mentioned that she goes hiking every weekend. " - "Her favorite trail is in Yosemite National Park.", - context="Casual conversation about hobbies", - event_date=utcnow() - timedelta(hours=2), - ) - - # Verify memory units were created - cursor = db_connection.cursor() - cursor.execute("SELECT COUNT(*) FROM memory_units WHERE agent_id = %s", (agent_id,)) - count = cursor.fetchone()[0] - - assert count > 0, "Memory units should be created" - assert count <= 3, "Should create approximately 3 units (one per sentence)" - - cursor.close() - - -@pytest.mark.asyncio -async def test_put_creates_temporal_links(memory, clean_agent, db_connection): - """Test that temporal links are created between recent memories.""" - agent_id = clean_agent - - # Store two memories close in time - await memory.put_async( - agent_id=agent_id, - content="Alice loves hiking.", - context="Hobbies", - event_date=utcnow() - timedelta(hours=2), - ) - - await memory.put_async( - agent_id=agent_id, - content="Bob enjoys climbing.", - context="Sports", - event_date=utcnow() - timedelta(hours=1), - ) - - # Verify temporal links were created - cursor = db_connection.cursor() - cursor.execute(""" - SELECT COUNT(*) - FROM memory_links - WHERE link_type = 'temporal' - AND from_unit_id IN ( - SELECT id FROM memory_units WHERE agent_id = %s - ) - """, (agent_id,)) - - temporal_link_count = cursor.fetchone()[0] - assert temporal_link_count > 0, "Temporal links should be created" - - cursor.close() - - -@pytest.mark.asyncio -async def test_put_creates_semantic_links(memory, clean_agent, db_connection): - """Test that semantic links are created between similar memories.""" - agent_id = clean_agent - - # Store semantically similar memories - await memory.put_async( - agent_id=agent_id, - content="Alice loves hiking in the mountains.", - context="Hobbies", - event_date=utcnow() - timedelta(days=2), - ) - - await memory.put_async( - agent_id=agent_id, - content="Bob enjoys climbing mountains.", - context="Sports", - event_date=utcnow(), - ) - - # Verify semantic links were created - cursor = db_connection.cursor() - cursor.execute(""" - SELECT COUNT(*) - FROM memory_links - WHERE link_type = 'semantic' - AND from_unit_id IN ( - SELECT id FROM memory_units WHERE agent_id = %s - ) - """, (agent_id,)) - - semantic_link_count = cursor.fetchone()[0] - # Semantic links may or may not be created depending on similarity threshold - # So we just check that the query works - assert semantic_link_count >= 0, "Query should execute successfully" - - cursor.close() - - -@pytest.mark.asyncio -async def test_search_with_spreading_activation(memory, clean_agent): - """Test search using spreading activation algorithm.""" - agent_id = clean_agent - - # Store memories about outdoor activities - await memory.put_async( - agent_id=agent_id, - content="Alice told me she loves hiking in the mountains. " - "She goes hiking every weekend.", - context="Casual conversation about hobbies", - event_date=utcnow() - timedelta(hours=2), - ) - - await memory.put_async( - agent_id=agent_id, - content="Bob mentioned he enjoys rock climbing. " - "He climbs mountains on weekends too.", - context="Discussion about outdoor sports", - event_date=utcnow() - timedelta(hours=1), - ) - - # Search for outdoor activities - results = memory.search( - agent_id=agent_id, - query="outdoor mountain activities", - thinking_budget=50, - top_k=5, - ) - - assert len(results) > 0, "Search should return results" - - # Verify result structure - for result in results: - assert 'id' in result, "Result should have id" - assert 'text' in result, "Result should have text" - assert 'weight' in result, "Result should have weight" - assert 'activation' in result, "Result should have activation" - assert 'recency' in result, "Result should have recency" - assert 'frequency' in result, "Result should have frequency" - - # Results should be sorted by weight (descending) - weights = [r['weight'] for r in results] - assert weights == sorted(weights, reverse=True), "Results should be sorted by weight" - - -@pytest.mark.asyncio -async def test_search_returns_relevant_memories(memory, clean_agent): - """Test that search returns semantically relevant memories.""" - agent_id = clean_agent - - # Store memories about different topics - await memory.put_async( - agent_id=agent_id, - content="Alice loves hiking in the mountains.", - context="Hobbies", - event_date=utcnow() - timedelta(hours=2), - ) - - await memory.put_async( - agent_id=agent_id, - content="Bob is working on a Python web application.", - context="Tech", - event_date=utcnow() - timedelta(hours=1), - ) - - # Search for programming-related memories - results = memory.search( - agent_id=agent_id, - query="software development", - thinking_budget=50, - top_k=3, - ) - - # Should find the programming-related memory - assert len(results) > 0, "Search should return results" - - # Top result should be about programming (more relevant) - top_result_text = results[0]['text'].lower() - assert 'python' in top_result_text or 'application' in top_result_text or 'working' in top_result_text, \ - "Top result should be about programming" - - -@pytest.mark.asyncio -async def test_search_with_no_results(memory, clean_agent): - """Test search behavior when no relevant memories exist.""" - agent_id = clean_agent - - # Store unrelated memories - await memory.put_async( - agent_id=agent_id, - content="Alice loves cooking pasta.", - context="Food", - event_date=utcnow(), - ) - - # Search for something completely unrelated - results = memory.search( - agent_id=agent_id, - query="quantum physics theories", - thinking_budget=20, - top_k=5, - ) - - # May return low-scoring results or empty list - assert isinstance(results, list), "Search should return a list" diff --git a/tests/test_temporal_extraction.py b/tests/test_temporal_extraction.py new file mode 100644 index 00000000..458960b4 --- /dev/null +++ b/tests/test_temporal_extraction.py @@ -0,0 +1,94 @@ +""" +Test temporal extraction and per-fact dating. +""" +import pytest +from datetime import datetime, timezone, timedelta +from memory.llm_client import extract_facts_from_text + + +@pytest.mark.asyncio +async def test_extract_facts_with_relative_dates(): + """Test that relative dates are converted to absolute dates.""" + + reference_date = datetime(2024, 3, 20, 14, 0, 0, tzinfo=timezone.utc) + + text = """ + Yesterday I went hiking in Yosemite. + Last week I started my new job at Google. + This morning I had coffee with Alice. + """ + + facts = await extract_facts_from_text(text, reference_date, "Personal diary") + + print(f"\nExtracted {len(facts)} facts:") + for fact in facts: + print(f"- {fact['fact']}") + print(f" Date: {fact['date']}") + + # Verify we got facts + assert len(facts) > 0, "Should extract at least one fact" + + # Check that all facts have dates + for fact in facts: + assert 'fact' in fact, "Each fact should have 'fact' field" + assert 'date' in fact, "Each fact should have 'date' field" + assert fact['date'], f"Date should not be empty for fact: {fact['fact']}" + + # Verify dates are different (not all using reference date) + dates = [f['date'] for f in facts] + unique_dates = set(dates) + if len(facts) >= 3: + assert len(unique_dates) >= 2, "Should have different dates for different temporal facts" + + print(f"\n✅ All facts have absolute dates") + + +@pytest.mark.asyncio +async def test_extract_facts_with_no_temporal_info(): + """Test that facts without temporal info use the reference date.""" + + reference_date = datetime(2024, 3, 20, 14, 0, 0, tzinfo=timezone.utc) + + text = "Alice works at Google. She loves Python programming." + + facts = await extract_facts_from_text(text, reference_date, "General info") + + print(f"\nExtracted {len(facts)} facts:") + for fact in facts: + print(f"- {fact['fact']}") + print(f" Date: {fact['date']}") + + assert len(facts) > 0, "Should extract at least one fact" + + # All facts should use the reference date since no temporal info is mentioned + for fact in facts: + assert fact['date'], f"Fact should have a date: {fact['fact']}" + + +@pytest.mark.asyncio +async def test_extract_facts_with_absolute_dates(): + """Test that absolute dates in text are preserved.""" + + reference_date = datetime(2024, 3, 20, 14, 0, 0, tzinfo=timezone.utc) + + text = """ + On March 15, 2024, Alice joined Google. + Bob will start his vacation on April 1st. + """ + + facts = await extract_facts_from_text(text, reference_date, "Calendar events") + + print(f"\nExtracted {len(facts)} facts:") + for fact in facts: + print(f"- {fact['fact']}") + print(f" Date: {fact['date']}") + + assert len(facts) > 0, "Should extract at least one fact" + + # Check that dates are present + for fact in facts: + assert fact['date'], f"Fact should have a date: {fact['fact']}" + + +if __name__ == "__main__": + pytest.main([__file__, "-v", "-s"]) diff --git a/tests/test_visualization.py b/tests/test_visualization.py deleted file mode 100644 index eaf83cb2..00000000 --- a/tests/test_visualization.py +++ /dev/null @@ -1,96 +0,0 @@ -""" -Test visualization functionality. - -Tests memory graph data retrieval (not actual rendering). -""" -import pytest -from datetime import datetime, timedelta, timezone - - -def utcnow(): - """Get current UTC time with timezone info.""" - return datetime.now(timezone.utc) - - -def test_get_memory_graph_data(memory, clean_agent): - """Test retrieval of memory graph data for visualization.""" - agent_id = clean_agent - - # Store some memories - memory.put( - agent_id=agent_id, - content="Alice loves hiking in the mountains.", - context="Hobbies", - event_date=utcnow() - timedelta(hours=2), - ) - - memory.put( - agent_id=agent_id, - content="Bob enjoys rock climbing.", - context="Sports", - event_date=utcnow() - timedelta(hours=1), - ) - - memory.put( - agent_id=agent_id, - content="Alice is working on a Python project.", - context="Tech", - event_date=utcnow(), - ) - - # Get graph data - units, links = memory.get_memory_graph_data(agent_id) - - assert isinstance(units, list), "Units should be a list" - assert isinstance(links, list), "Links should be a list" - assert len(units) > 0, "Should have memory units" - - # Verify unit structure - for unit in units: - assert 'id' in unit, "Unit should have id" - assert 'text' in unit, "Unit should have text" - assert 'context' in unit, "Unit should have context" - assert 'event_date' in unit, "Unit should have event_date" - assert 'access_count' in unit, "Unit should have access_count" - - # Links may or may not exist depending on similarity/proximity - if len(links) > 0: - # Verify link structure - for link in links: - assert 'from_unit_id' in link, "Link should have from_unit_id" - assert 'to_unit_id' in link, "Link should have to_unit_id" - assert 'link_type' in link, "Link should have link_type" - assert 'weight' in link, "Link should have weight" - assert link['link_type'] in ['temporal', 'semantic', 'entity'], \ - "Link type should be temporal, semantic, or entity" - - -def test_memory_graph_has_correct_agent_data(memory, clean_agent): - """Test that graph data only includes data for the specified agent.""" - agent_id = clean_agent - other_agent_id = "other_agent" - - # Store memories for test agent - memory.put( - agent_id=agent_id, - content="Alice loves hiking.", - context="Hobbies", - event_date=utcnow(), - ) - - # Store memories for another agent - memory.put( - agent_id=other_agent_id, - content="Charlie enjoys swimming.", - context="Sports", - event_date=utcnow(), - ) - - # Get graph data for test agent - units, links = memory.get_memory_graph_data(agent_id) - - # Should only include test agent's data - for unit in units: - # Verify by checking text content (Alice should be present, Charlie should not) - unit_text = unit['text'] - assert 'Charlie' not in unit_text, "Should not include other agent's memories" diff --git a/uv.lock b/uv.lock index f1856fa9..b3529c00 100644 --- a/uv.lock +++ b/uv.lock @@ -6,130 +6,6 @@ resolution-markers = [ "python_full_version < '3.12'", ] -[[package]] -name = "aiohappyeyeballs" -version = "2.6.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", size = 22760 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", size = 15265 }, -] - -[[package]] -name = "aiohttp" -version = "3.13.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "aiohappyeyeballs" }, - { name = "aiosignal" }, - { name = "attrs" }, - { name = "frozenlist" }, - { name = "multidict" }, - { name = "propcache" }, - { name = "yarl" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/1c/ce/3b83ebba6b3207a7135e5fcaba49706f8a4b6008153b4e30540c982fae26/aiohttp-3.13.2.tar.gz", hash = "sha256:40176a52c186aefef6eb3cad2cdd30cd06e3afbe88fe8ab2af9c0b90f228daca", size = 7837994 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/35/74/b321e7d7ca762638cdf8cdeceb39755d9c745aff7a64c8789be96ddf6e96/aiohttp-3.13.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4647d02df098f6434bafd7f32ad14942f05a9caa06c7016fdcc816f343997dd0", size = 743409 }, - { url = "https://files.pythonhosted.org/packages/99/3d/91524b905ec473beaf35158d17f82ef5a38033e5809fe8742e3657cdbb97/aiohttp-3.13.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e3403f24bcb9c3b29113611c3c16a2a447c3953ecf86b79775e7be06f7ae7ccb", size = 497006 }, - { url = "https://files.pythonhosted.org/packages/eb/d3/7f68bc02a67716fe80f063e19adbd80a642e30682ce74071269e17d2dba1/aiohttp-3.13.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:43dff14e35aba17e3d6d5ba628858fb8cb51e30f44724a2d2f0c75be492c55e9", size = 493195 }, - { url = "https://files.pythonhosted.org/packages/98/31/913f774a4708775433b7375c4f867d58ba58ead833af96c8af3621a0d243/aiohttp-3.13.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e2a9ea08e8c58bb17655630198833109227dea914cd20be660f52215f6de5613", size = 1747759 }, - { url = "https://files.pythonhosted.org/packages/e8/63/04efe156f4326f31c7c4a97144f82132c3bb21859b7bb84748d452ccc17c/aiohttp-3.13.2-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53b07472f235eb80e826ad038c9d106c2f653584753f3ddab907c83f49eedead", size = 1704456 }, - { url = "https://files.pythonhosted.org/packages/8e/02/4e16154d8e0a9cf4ae76f692941fd52543bbb148f02f098ca73cab9b1c1b/aiohttp-3.13.2-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e736c93e9c274fce6419af4aac199984d866e55f8a4cec9114671d0ea9688780", size = 1807572 }, - { url = "https://files.pythonhosted.org/packages/34/58/b0583defb38689e7f06798f0285b1ffb3a6fb371f38363ce5fd772112724/aiohttp-3.13.2-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ff5e771f5dcbc81c64898c597a434f7682f2259e0cd666932a913d53d1341d1a", size = 1895954 }, - { url = "https://files.pythonhosted.org/packages/6b/f3/083907ee3437425b4e376aa58b2c915eb1a33703ec0dc30040f7ae3368c6/aiohttp-3.13.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3b6fb0c207cc661fa0bf8c66d8d9b657331ccc814f4719468af61034b478592", size = 1747092 }, - { url = "https://files.pythonhosted.org/packages/ac/61/98a47319b4e425cc134e05e5f3fc512bf9a04bf65aafd9fdcda5d57ec693/aiohttp-3.13.2-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:97a0895a8e840ab3520e2288db7cace3a1981300d48babeb50e7425609e2e0ab", size = 1606815 }, - { url = "https://files.pythonhosted.org/packages/97/4b/e78b854d82f66bb974189135d31fce265dee0f5344f64dd0d345158a5973/aiohttp-3.13.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9e8f8afb552297aca127c90cb840e9a1d4bfd6a10d7d8f2d9176e1acc69bad30", size = 1723789 }, - { url = "https://files.pythonhosted.org/packages/ed/fc/9d2ccc794fc9b9acd1379d625c3a8c64a45508b5091c546dea273a41929e/aiohttp-3.13.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ed2f9c7216e53c3df02264f25d824b079cc5914f9e2deba94155190ef648ee40", size = 1718104 }, - { url = "https://files.pythonhosted.org/packages/66/65/34564b8765ea5c7d79d23c9113135d1dd3609173da13084830f1507d56cf/aiohttp-3.13.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:99c5280a329d5fa18ef30fd10c793a190d996567667908bef8a7f81f8202b948", size = 1785584 }, - { url = "https://files.pythonhosted.org/packages/30/be/f6a7a426e02fc82781afd62016417b3948e2207426d90a0e478790d1c8a4/aiohttp-3.13.2-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:2ca6ffef405fc9c09a746cb5d019c1672cd7f402542e379afc66b370833170cf", size = 1595126 }, - { url = "https://files.pythonhosted.org/packages/e5/c7/8e22d5d28f94f67d2af496f14a83b3c155d915d1fe53d94b66d425ec5b42/aiohttp-3.13.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:47f438b1a28e926c37632bff3c44df7d27c9b57aaf4e34b1def3c07111fdb782", size = 1800665 }, - { url = "https://files.pythonhosted.org/packages/d1/11/91133c8b68b1da9fc16555706aa7276fdf781ae2bb0876c838dd86b8116e/aiohttp-3.13.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9acda8604a57bb60544e4646a4615c1866ee6c04a8edef9b8ee6fd1d8fa2ddc8", size = 1739532 }, - { url = "https://files.pythonhosted.org/packages/17/6b/3747644d26a998774b21a616016620293ddefa4d63af6286f389aedac844/aiohttp-3.13.2-cp311-cp311-win32.whl", hash = "sha256:868e195e39b24aaa930b063c08bb0c17924899c16c672a28a65afded9c46c6ec", size = 431876 }, - { url = "https://files.pythonhosted.org/packages/c3/63/688462108c1a00eb9f05765331c107f95ae86f6b197b865d29e930b7e462/aiohttp-3.13.2-cp311-cp311-win_amd64.whl", hash = "sha256:7fd19df530c292542636c2a9a85854fab93474396a52f1695e799186bbd7f24c", size = 456205 }, - { url = "https://files.pythonhosted.org/packages/29/9b/01f00e9856d0a73260e86dd8ed0c2234a466c5c1712ce1c281548df39777/aiohttp-3.13.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:b1e56bab2e12b2b9ed300218c351ee2a3d8c8fdab5b1ec6193e11a817767e47b", size = 737623 }, - { url = "https://files.pythonhosted.org/packages/5a/1b/4be39c445e2b2bd0aab4ba736deb649fabf14f6757f405f0c9685019b9e9/aiohttp-3.13.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:364e25edaabd3d37b1db1f0cbcee8c73c9a3727bfa262b83e5e4cf3489a2a9dc", size = 492664 }, - { url = "https://files.pythonhosted.org/packages/28/66/d35dcfea8050e131cdd731dff36434390479b4045a8d0b9d7111b0a968f1/aiohttp-3.13.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c5c94825f744694c4b8db20b71dba9a257cd2ba8e010a803042123f3a25d50d7", size = 491808 }, - { url = "https://files.pythonhosted.org/packages/00/29/8e4609b93e10a853b65f8291e64985de66d4f5848c5637cddc70e98f01f8/aiohttp-3.13.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba2715d842ffa787be87cbfce150d5e88c87a98e0b62e0f5aa489169a393dbbb", size = 1738863 }, - { url = "https://files.pythonhosted.org/packages/9d/fa/4ebdf4adcc0def75ced1a0d2d227577cd7b1b85beb7edad85fcc87693c75/aiohttp-3.13.2-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:585542825c4bc662221fb257889e011a5aa00f1ae4d75d1d246a5225289183e3", size = 1700586 }, - { url = "https://files.pythonhosted.org/packages/da/04/73f5f02ff348a3558763ff6abe99c223381b0bace05cd4530a0258e52597/aiohttp-3.13.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:39d02cb6025fe1aabca329c5632f48c9532a3dabccd859e7e2f110668972331f", size = 1768625 }, - { url = "https://files.pythonhosted.org/packages/f8/49/a825b79ffec124317265ca7d2344a86bcffeb960743487cb11988ffb3494/aiohttp-3.13.2-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e67446b19e014d37342f7195f592a2a948141d15a312fe0e700c2fd2f03124f6", size = 1867281 }, - { url = "https://files.pythonhosted.org/packages/b9/48/adf56e05f81eac31edcfae45c90928f4ad50ef2e3ea72cb8376162a368f8/aiohttp-3.13.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4356474ad6333e41ccefd39eae869ba15a6c5299c9c01dfdcfdd5c107be4363e", size = 1752431 }, - { url = "https://files.pythonhosted.org/packages/30/ab/593855356eead019a74e862f21523db09c27f12fd24af72dbc3555b9bfd9/aiohttp-3.13.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:eeacf451c99b4525f700f078becff32c32ec327b10dcf31306a8a52d78166de7", size = 1562846 }, - { url = "https://files.pythonhosted.org/packages/39/0f/9f3d32271aa8dc35036e9668e31870a9d3b9542dd6b3e2c8a30931cb27ae/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d8a9b889aeabd7a4e9af0b7f4ab5ad94d42e7ff679aaec6d0db21e3b639ad58d", size = 1699606 }, - { url = "https://files.pythonhosted.org/packages/2c/3c/52d2658c5699b6ef7692a3f7128b2d2d4d9775f2a68093f74bca06cf01e1/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:fa89cb11bc71a63b69568d5b8a25c3ca25b6d54c15f907ca1c130d72f320b76b", size = 1720663 }, - { url = "https://files.pythonhosted.org/packages/9b/d4/8f8f3ff1fb7fb9e3f04fcad4e89d8a1cd8fc7d05de67e3de5b15b33008ff/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8aa7c807df234f693fed0ecd507192fc97692e61fee5702cdc11155d2e5cadc8", size = 1737939 }, - { url = "https://files.pythonhosted.org/packages/03/d3/ddd348f8a27a634daae39a1b8e291ff19c77867af438af844bf8b7e3231b/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:9eb3e33fdbe43f88c3c75fa608c25e7c47bbd80f48d012763cb67c47f39a7e16", size = 1555132 }, - { url = "https://files.pythonhosted.org/packages/39/b8/46790692dc46218406f94374903ba47552f2f9f90dad554eed61bfb7b64c/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9434bc0d80076138ea986833156c5a48c9c7a8abb0c96039ddbb4afc93184169", size = 1764802 }, - { url = "https://files.pythonhosted.org/packages/ba/e4/19ce547b58ab2a385e5f0b8aa3db38674785085abcf79b6e0edd1632b12f/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ff15c147b2ad66da1f2cbb0622313f2242d8e6e8f9b79b5206c84523a4473248", size = 1719512 }, - { url = "https://files.pythonhosted.org/packages/70/30/6355a737fed29dcb6dfdd48682d5790cb5eab050f7b4e01f49b121d3acad/aiohttp-3.13.2-cp312-cp312-win32.whl", hash = "sha256:27e569eb9d9e95dbd55c0fc3ec3a9335defbf1d8bc1d20171a49f3c4c607b93e", size = 426690 }, - { url = "https://files.pythonhosted.org/packages/0a/0d/b10ac09069973d112de6ef980c1f6bb31cb7dcd0bc363acbdad58f927873/aiohttp-3.13.2-cp312-cp312-win_amd64.whl", hash = "sha256:8709a0f05d59a71f33fd05c17fc11fcb8c30140506e13c2f5e8ee1b8964e1b45", size = 453465 }, - { url = "https://files.pythonhosted.org/packages/bf/78/7e90ca79e5aa39f9694dcfd74f4720782d3c6828113bb1f3197f7e7c4a56/aiohttp-3.13.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7519bdc7dfc1940d201651b52bf5e03f5503bda45ad6eacf64dda98be5b2b6be", size = 732139 }, - { url = "https://files.pythonhosted.org/packages/db/ed/1f59215ab6853fbaa5c8495fa6cbc39edfc93553426152b75d82a5f32b76/aiohttp-3.13.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:088912a78b4d4f547a1f19c099d5a506df17eacec3c6f4375e2831ec1d995742", size = 490082 }, - { url = "https://files.pythonhosted.org/packages/68/7b/fe0fe0f5e05e13629d893c760465173a15ad0039c0a5b0d0040995c8075e/aiohttp-3.13.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5276807b9de9092af38ed23ce120539ab0ac955547b38563a9ba4f5b07b95293", size = 489035 }, - { url = "https://files.pythonhosted.org/packages/d2/04/db5279e38471b7ac801d7d36a57d1230feeee130bbe2a74f72731b23c2b1/aiohttp-3.13.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1237c1375eaef0db4dcd7c2559f42e8af7b87ea7d295b118c60c36a6e61cb811", size = 1720387 }, - { url = "https://files.pythonhosted.org/packages/31/07/8ea4326bd7dae2bd59828f69d7fdc6e04523caa55e4a70f4a8725a7e4ed2/aiohttp-3.13.2-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:96581619c57419c3d7d78703d5b78c1e5e5fc0172d60f555bdebaced82ded19a", size = 1688314 }, - { url = "https://files.pythonhosted.org/packages/48/ab/3d98007b5b87ffd519d065225438cc3b668b2f245572a8cb53da5dd2b1bc/aiohttp-3.13.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a2713a95b47374169409d18103366de1050fe0ea73db358fc7a7acb2880422d4", size = 1756317 }, - { url = "https://files.pythonhosted.org/packages/97/3d/801ca172b3d857fafb7b50c7c03f91b72b867a13abca982ed6b3081774ef/aiohttp-3.13.2-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:228a1cd556b3caca590e9511a89444925da87d35219a49ab5da0c36d2d943a6a", size = 1858539 }, - { url = "https://files.pythonhosted.org/packages/f7/0d/4764669bdf47bd472899b3d3db91fffbe925c8e3038ec591a2fd2ad6a14d/aiohttp-3.13.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ac6cde5fba8d7d8c6ac963dbb0256a9854e9fafff52fbcc58fdf819357892c3e", size = 1739597 }, - { url = "https://files.pythonhosted.org/packages/c4/52/7bd3c6693da58ba16e657eb904a5b6decfc48ecd06e9ac098591653b1566/aiohttp-3.13.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f2bef8237544f4e42878c61cef4e2839fee6346dc60f5739f876a9c50be7fcdb", size = 1555006 }, - { url = "https://files.pythonhosted.org/packages/48/30/9586667acec5993b6f41d2ebcf96e97a1255a85f62f3c653110a5de4d346/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:16f15a4eac3bc2d76c45f7ebdd48a65d41b242eb6c31c2245463b40b34584ded", size = 1683220 }, - { url = "https://files.pythonhosted.org/packages/71/01/3afe4c96854cfd7b30d78333852e8e851dceaec1c40fd00fec90c6402dd2/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:bb7fb776645af5cc58ab804c58d7eba545a97e047254a52ce89c157b5af6cd0b", size = 1712570 }, - { url = "https://files.pythonhosted.org/packages/11/2c/22799d8e720f4697a9e66fd9c02479e40a49de3de2f0bbe7f9f78a987808/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:e1b4951125ec10c70802f2cb09736c895861cd39fd9dcb35107b4dc8ae6220b8", size = 1733407 }, - { url = "https://files.pythonhosted.org/packages/34/cb/90f15dd029f07cebbd91f8238a8b363978b530cd128488085b5703683594/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:550bf765101ae721ee1d37d8095f47b1f220650f85fe1af37a90ce75bab89d04", size = 1550093 }, - { url = "https://files.pythonhosted.org/packages/69/46/12dce9be9d3303ecbf4d30ad45a7683dc63d90733c2d9fe512be6716cd40/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fe91b87fc295973096251e2d25a811388e7d8adf3bd2b97ef6ae78bc4ac6c476", size = 1758084 }, - { url = "https://files.pythonhosted.org/packages/f9/c8/0932b558da0c302ffd639fc6362a313b98fdf235dc417bc2493da8394df7/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e0c8e31cfcc4592cb200160344b2fb6ae0f9e4effe06c644b5a125d4ae5ebe23", size = 1716987 }, - { url = "https://files.pythonhosted.org/packages/5d/8b/f5bd1a75003daed099baec373aed678f2e9b34f2ad40d85baa1368556396/aiohttp-3.13.2-cp313-cp313-win32.whl", hash = "sha256:0740f31a60848d6edb296a0df827473eede90c689b8f9f2a4cdde74889eb2254", size = 425859 }, - { url = "https://files.pythonhosted.org/packages/5d/28/a8a9fc6957b2cee8902414e41816b5ab5536ecf43c3b1843c10e82c559b2/aiohttp-3.13.2-cp313-cp313-win_amd64.whl", hash = "sha256:a88d13e7ca367394908f8a276b89d04a3652044612b9a408a0bb22a5ed976a1a", size = 452192 }, - { url = "https://files.pythonhosted.org/packages/9b/36/e2abae1bd815f01c957cbf7be817b3043304e1c87bad526292a0410fdcf9/aiohttp-3.13.2-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:2475391c29230e063ef53a66669b7b691c9bfc3f1426a0f7bcdf1216bdbac38b", size = 735234 }, - { url = "https://files.pythonhosted.org/packages/ca/e3/1ee62dde9b335e4ed41db6bba02613295a0d5b41f74a783c142745a12763/aiohttp-3.13.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:f33c8748abef4d8717bb20e8fb1b3e07c6adacb7fd6beaae971a764cf5f30d61", size = 490733 }, - { url = "https://files.pythonhosted.org/packages/1a/aa/7a451b1d6a04e8d15a362af3e9b897de71d86feac3babf8894545d08d537/aiohttp-3.13.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ae32f24bbfb7dbb485a24b30b1149e2f200be94777232aeadba3eecece4d0aa4", size = 491303 }, - { url = "https://files.pythonhosted.org/packages/57/1e/209958dbb9b01174870f6a7538cd1f3f28274fdbc88a750c238e2c456295/aiohttp-3.13.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d7f02042c1f009ffb70067326ef183a047425bb2ff3bc434ead4dd4a4a66a2b", size = 1717965 }, - { url = "https://files.pythonhosted.org/packages/08/aa/6a01848d6432f241416bc4866cae8dc03f05a5a884d2311280f6a09c73d6/aiohttp-3.13.2-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:93655083005d71cd6c072cdab54c886e6570ad2c4592139c3fb967bfc19e4694", size = 1667221 }, - { url = "https://files.pythonhosted.org/packages/87/4f/36c1992432d31bbc789fa0b93c768d2e9047ec8c7177e5cd84ea85155f36/aiohttp-3.13.2-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0db1e24b852f5f664cd728db140cf11ea0e82450471232a394b3d1a540b0f906", size = 1757178 }, - { url = "https://files.pythonhosted.org/packages/ac/b4/8e940dfb03b7e0f68a82b88fd182b9be0a65cb3f35612fe38c038c3112cf/aiohttp-3.13.2-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b009194665bcd128e23eaddef362e745601afa4641930848af4c8559e88f18f9", size = 1838001 }, - { url = "https://files.pythonhosted.org/packages/d7/ef/39f3448795499c440ab66084a9db7d20ca7662e94305f175a80f5b7e0072/aiohttp-3.13.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c038a8fdc8103cd51dbd986ecdce141473ffd9775a7a8057a6ed9c3653478011", size = 1716325 }, - { url = "https://files.pythonhosted.org/packages/d7/51/b311500ffc860b181c05d91c59a1313bdd05c82960fdd4035a15740d431e/aiohttp-3.13.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:66bac29b95a00db411cd758fea0e4b9bdba6d549dfe333f9a945430f5f2cc5a6", size = 1547978 }, - { url = "https://files.pythonhosted.org/packages/31/64/b9d733296ef79815226dab8c586ff9e3df41c6aff2e16c06697b2d2e6775/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4ebf9cfc9ba24a74cf0718f04aac2a3bbe745902cc7c5ebc55c0f3b5777ef213", size = 1682042 }, - { url = "https://files.pythonhosted.org/packages/3f/30/43d3e0f9d6473a6db7d472104c4eff4417b1e9df01774cb930338806d36b/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a4b88ebe35ce54205c7074f7302bd08a4cb83256a3e0870c72d6f68a3aaf8e49", size = 1680085 }, - { url = "https://files.pythonhosted.org/packages/16/51/c709f352c911b1864cfd1087577760ced64b3e5bee2aa88b8c0c8e2e4972/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:98c4fb90bb82b70a4ed79ca35f656f4281885be076f3f970ce315402b53099ae", size = 1728238 }, - { url = "https://files.pythonhosted.org/packages/19/e2/19bd4c547092b773caeb48ff5ae4b1ae86756a0ee76c16727fcfd281404b/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:ec7534e63ae0f3759df3a1ed4fa6bc8f75082a924b590619c0dd2f76d7043caa", size = 1544395 }, - { url = "https://files.pythonhosted.org/packages/cf/87/860f2803b27dfc5ed7be532832a3498e4919da61299b4a1f8eb89b8ff44d/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5b927cf9b935a13e33644cbed6c8c4b2d0f25b713d838743f8fe7191b33829c4", size = 1742965 }, - { url = "https://files.pythonhosted.org/packages/67/7f/db2fc7618925e8c7a601094d5cbe539f732df4fb570740be88ed9e40e99a/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:88d6c017966a78c5265d996c19cdb79235be5e6412268d7e2ce7dee339471b7a", size = 1697585 }, - { url = "https://files.pythonhosted.org/packages/0c/07/9127916cb09bb38284db5036036042b7b2c514c8ebaeee79da550c43a6d6/aiohttp-3.13.2-cp314-cp314-win32.whl", hash = "sha256:f7c183e786e299b5d6c49fb43a769f8eb8e04a2726a2bd5887b98b5cc2d67940", size = 431621 }, - { url = "https://files.pythonhosted.org/packages/fb/41/554a8a380df6d3a2bba8a7726429a23f4ac62aaf38de43bb6d6cde7b4d4d/aiohttp-3.13.2-cp314-cp314-win_amd64.whl", hash = "sha256:fe242cd381e0fb65758faf5ad96c2e460df6ee5b2de1072fe97e4127927e00b4", size = 457627 }, - { url = "https://files.pythonhosted.org/packages/c7/8e/3824ef98c039d3951cb65b9205a96dd2b20f22241ee17d89c5701557c826/aiohttp-3.13.2-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:f10d9c0b0188fe85398c61147bbd2a657d616c876863bfeff43376e0e3134673", size = 767360 }, - { url = "https://files.pythonhosted.org/packages/a4/0f/6a03e3fc7595421274fa34122c973bde2d89344f8a881b728fa8c774e4f1/aiohttp-3.13.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:e7c952aefdf2460f4ae55c5e9c3e80aa72f706a6317e06020f80e96253b1accd", size = 504616 }, - { url = "https://files.pythonhosted.org/packages/c6/aa/ed341b670f1bc8a6f2c6a718353d13b9546e2cef3544f573c6a1ff0da711/aiohttp-3.13.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c20423ce14771d98353d2e25e83591fa75dfa90a3c1848f3d7c68243b4fbded3", size = 509131 }, - { url = "https://files.pythonhosted.org/packages/7f/f0/c68dac234189dae5c4bbccc0f96ce0cc16b76632cfc3a08fff180045cfa4/aiohttp-3.13.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e96eb1a34396e9430c19d8338d2ec33015e4a87ef2b4449db94c22412e25ccdf", size = 1864168 }, - { url = "https://files.pythonhosted.org/packages/8f/65/75a9a76db8364b5d0e52a0c20eabc5d52297385d9af9c35335b924fafdee/aiohttp-3.13.2-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:23fb0783bc1a33640036465019d3bba069942616a6a2353c6907d7fe1ccdaf4e", size = 1719200 }, - { url = "https://files.pythonhosted.org/packages/f5/55/8df2ed78d7f41d232f6bd3ff866b6f617026551aa1d07e2f03458f964575/aiohttp-3.13.2-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2e1a9bea6244a1d05a4e57c295d69e159a5c50d8ef16aa390948ee873478d9a5", size = 1843497 }, - { url = "https://files.pythonhosted.org/packages/e9/e0/94d7215e405c5a02ccb6a35c7a3a6cfff242f457a00196496935f700cde5/aiohttp-3.13.2-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0a3d54e822688b56e9f6b5816fb3de3a3a64660efac64e4c2dc435230ad23bad", size = 1935703 }, - { url = "https://files.pythonhosted.org/packages/0b/78/1eeb63c3f9b2d1015a4c02788fb543141aad0a03ae3f7a7b669b2483f8d4/aiohttp-3.13.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7a653d872afe9f33497215745da7a943d1dc15b728a9c8da1c3ac423af35178e", size = 1792738 }, - { url = "https://files.pythonhosted.org/packages/41/75/aaf1eea4c188e51538c04cc568040e3082db263a57086ea74a7d38c39e42/aiohttp-3.13.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:56d36e80d2003fa3fc0207fac644216d8532e9504a785ef9a8fd013f84a42c61", size = 1624061 }, - { url = "https://files.pythonhosted.org/packages/9b/c2/3b6034de81fbcc43de8aeb209073a2286dfb50b86e927b4efd81cf848197/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:78cd586d8331fb8e241c2dd6b2f4061778cc69e150514b39a9e28dd050475661", size = 1789201 }, - { url = "https://files.pythonhosted.org/packages/c9/38/c15dcf6d4d890217dae79d7213988f4e5fe6183d43893a9cf2fe9e84ca8d/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:20b10bbfbff766294fe99987f7bb3b74fdd2f1a2905f2562132641ad434dcf98", size = 1776868 }, - { url = "https://files.pythonhosted.org/packages/04/75/f74fd178ac81adf4f283a74847807ade5150e48feda6aef024403716c30c/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:9ec49dff7e2b3c85cdeaa412e9d438f0ecd71676fde61ec57027dd392f00c693", size = 1790660 }, - { url = "https://files.pythonhosted.org/packages/e7/80/7368bd0d06b16b3aba358c16b919e9c46cf11587dc572091031b0e9e3ef0/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:94f05348c4406450f9d73d38efb41d669ad6cd90c7ee194810d0eefbfa875a7a", size = 1617548 }, - { url = "https://files.pythonhosted.org/packages/7d/4b/a6212790c50483cb3212e507378fbe26b5086d73941e1ec4b56a30439688/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:fa4dcb605c6f82a80c7f95713c2b11c3b8e9893b3ebd2bc9bde93165ed6107be", size = 1817240 }, - { url = "https://files.pythonhosted.org/packages/ff/f7/ba5f0ba4ea8d8f3c32850912944532b933acbf0f3a75546b89269b9b7dde/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cf00e5db968c3f67eccd2778574cf64d8b27d95b237770aa32400bd7a1ca4f6c", size = 1762334 }, - { url = "https://files.pythonhosted.org/packages/7e/83/1a5a1856574588b1cad63609ea9ad75b32a8353ac995d830bf5da9357364/aiohttp-3.13.2-cp314-cp314t-win32.whl", hash = "sha256:d23b5fe492b0805a50d3371e8a728a9134d8de5447dce4c885f5587294750734", size = 464685 }, - { url = "https://files.pythonhosted.org/packages/9f/4d/d22668674122c08f4d56972297c51a624e64b3ed1efaa40187607a7cb66e/aiohttp-3.13.2-cp314-cp314t-win_amd64.whl", hash = "sha256:ff0a7b0a82a7ab905cbda74006318d1b12e37c797eb1b0d4eb3e316cf47f658f", size = 498093 }, -] - -[[package]] -name = "aiosignal" -version = "1.4.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "frozenlist" }, - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490 }, -] - [[package]] name = "annotated-types" version = "0.7.0" @@ -153,24 +29,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/15/b3/9b1a8074496371342ec1e796a96f99c82c945a339cd81a8e73de28b4cf9e/anyio-4.11.0-py3-none-any.whl", hash = "sha256:0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc", size = 109097 }, ] -[[package]] -name = "asttokens" -version = "3.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4a/e7/82da0a03e7ba5141f05cce0d302e6eed121ae055e0456ca228bf693984bc/asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7", size = 61978 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/25/8a/c46dcc25341b5bce5472c718902eb3d38600a903b14fa6aeecef3f21a46f/asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2", size = 26918 }, -] - -[[package]] -name = "attrs" -version = "25.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6b/5c/685e6633917e101e5dcb62b9dd76946cbb57c26e133bae9e0cd36033c0a9/attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11", size = 934251 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615 }, -] - [[package]] name = "blis" version = "1.3.0" @@ -463,49 +321,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/74/65/c162fbac63e867a055240b6600b92ef96c0eb7a1895312ac53c4be93d056/cymem-2.0.11-cp313-cp313-win_amd64.whl", hash = "sha256:25da111adf425c29af0cfd9fecfec1c71c8d82e2244a85166830a0817a66ada7", size = 39090 }, ] -[[package]] -name = "datasets" -version = "4.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "dill" }, - { name = "filelock" }, - { name = "fsspec", extra = ["http"] }, - { name = "httpx" }, - { name = "huggingface-hub" }, - { name = "multiprocess" }, - { name = "numpy" }, - { name = "packaging" }, - { name = "pandas" }, - { name = "pyarrow" }, - { name = "pyyaml" }, - { name = "requests" }, - { name = "tqdm" }, - { name = "xxhash" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/2a/47/325206ac160f7699ed9f1798afa8f8f8d5189b03bf3815654859ac1d5cba/datasets-4.3.0.tar.gz", hash = "sha256:bc9118ed9afd92346c5be7ed3aaa00177eb907c25467f9d072a0d22777efbd2b", size = 582801 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ca/51/409a8184ed35453d9cbb3d6b20d524b1115c2c2d117b85d5e9b06cd70b45/datasets-4.3.0-py3-none-any.whl", hash = "sha256:0ea157e72138b3ca6c7d2415f19a164ecf7d4c4fa72da2a570da286882e96903", size = 506846 }, -] - -[[package]] -name = "decorator" -version = "5.2.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/43/fa/6d96a0978d19e17b68d634497769987b16c8f4cd0a7a05048bec693caa6b/decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360", size = 56711 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a", size = 9190 }, -] - -[[package]] -name = "dill" -version = "0.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/12/80/630b4b88364e9a8c8c5797f4602d0f76ef820909ee32f0bacb9f90654042/dill-0.4.0.tar.gz", hash = "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0", size = 186976 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049", size = 119668 }, -] - [[package]] name = "distro" version = "1.9.0" @@ -515,30 +330,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277 }, ] -[[package]] -name = "executing" -version = "2.2.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cc/28/c14e053b6762b1044f34a13aab6859bbf40456d37d23aa286ac24cfd9a5d/executing-2.2.1.tar.gz", hash = "sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4", size = 1129488 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl", hash = "sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017", size = 28317 }, -] - -[[package]] -name = "fastcoref" -version = "2.1.6" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "datasets" }, - { name = "numpy" }, - { name = "scipy" }, - { name = "spacy" }, - { name = "torch" }, - { name = "tqdm" }, - { name = "transformers" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/5c/35/d8e3906a6887e7dfbaf1d09fc9a7c16f117064eefc139ddacf7595b0db20/fastcoref-2.1.6.tar.gz", hash = "sha256:cf3bc2764cca1db06df8ff40e513d7f79d26f0c340d0e442bd66a85673610b9e", size = 27476 } - [[package]] name = "filelock" version = "3.20.0" @@ -597,111 +388,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c7/93/0dd45cd283c32dea1545151d8c3637b4b8c53cdb3a625aeb2885b184d74d/fonttools-4.60.1-py3-none-any.whl", hash = "sha256:906306ac7afe2156fcf0042173d6ebbb05416af70f6b370967b47f8f00103bbb", size = 1143175 }, ] -[[package]] -name = "frozenlist" -version = "1.8.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2d/f5/c831fac6cc817d26fd54c7eaccd04ef7e0288806943f7cc5bbf69f3ac1f0/frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad", size = 45875 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bc/03/077f869d540370db12165c0aa51640a873fb661d8b315d1d4d67b284d7ac/frozenlist-1.8.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:09474e9831bc2b2199fad6da3c14c7b0fbdd377cce9d3d77131be28906cb7d84", size = 86912 }, - { url = "https://files.pythonhosted.org/packages/df/b5/7610b6bd13e4ae77b96ba85abea1c8cb249683217ef09ac9e0ae93f25a91/frozenlist-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:17c883ab0ab67200b5f964d2b9ed6b00971917d5d8a92df149dc2c9779208ee9", size = 50046 }, - { url = "https://files.pythonhosted.org/packages/6e/ef/0e8f1fe32f8a53dd26bdd1f9347efe0778b0fddf62789ea683f4cc7d787d/frozenlist-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa47e444b8ba08fffd1c18e8cdb9a75db1b6a27f17507522834ad13ed5922b93", size = 50119 }, - { url = "https://files.pythonhosted.org/packages/11/b1/71a477adc7c36e5fb628245dfbdea2166feae310757dea848d02bd0689fd/frozenlist-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2552f44204b744fba866e573be4c1f9048d6a324dfe14475103fd51613eb1d1f", size = 231067 }, - { url = "https://files.pythonhosted.org/packages/45/7e/afe40eca3a2dc19b9904c0f5d7edfe82b5304cb831391edec0ac04af94c2/frozenlist-1.8.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:957e7c38f250991e48a9a73e6423db1bb9dd14e722a10f6b8bb8e16a0f55f695", size = 233160 }, - { url = "https://files.pythonhosted.org/packages/a6/aa/7416eac95603ce428679d273255ffc7c998d4132cfae200103f164b108aa/frozenlist-1.8.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8585e3bb2cdea02fc88ffa245069c36555557ad3609e83be0ec71f54fd4abb52", size = 228544 }, - { url = "https://files.pythonhosted.org/packages/8b/3d/2a2d1f683d55ac7e3875e4263d28410063e738384d3adc294f5ff3d7105e/frozenlist-1.8.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:edee74874ce20a373d62dc28b0b18b93f645633c2943fd90ee9d898550770581", size = 243797 }, - { url = "https://files.pythonhosted.org/packages/78/1e/2d5565b589e580c296d3bb54da08d206e797d941a83a6fdea42af23be79c/frozenlist-1.8.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c9a63152fe95756b85f31186bddf42e4c02c6321207fd6601a1c89ebac4fe567", size = 247923 }, - { url = "https://files.pythonhosted.org/packages/aa/c3/65872fcf1d326a7f101ad4d86285c403c87be7d832b7470b77f6d2ed5ddc/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b6db2185db9be0a04fecf2f241c70b63b1a242e2805be291855078f2b404dd6b", size = 230886 }, - { url = "https://files.pythonhosted.org/packages/a0/76/ac9ced601d62f6956f03cc794f9e04c81719509f85255abf96e2510f4265/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:f4be2e3d8bc8aabd566f8d5b8ba7ecc09249d74ba3c9ed52e54dc23a293f0b92", size = 245731 }, - { url = "https://files.pythonhosted.org/packages/b9/49/ecccb5f2598daf0b4a1415497eba4c33c1e8ce07495eb07d2860c731b8d5/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c8d1634419f39ea6f5c427ea2f90ca85126b54b50837f31497f3bf38266e853d", size = 241544 }, - { url = "https://files.pythonhosted.org/packages/53/4b/ddf24113323c0bbcc54cb38c8b8916f1da7165e07b8e24a717b4a12cbf10/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:1a7fa382a4a223773ed64242dbe1c9c326ec09457e6b8428efb4118c685c3dfd", size = 241806 }, - { url = "https://files.pythonhosted.org/packages/a7/fb/9b9a084d73c67175484ba2789a59f8eebebd0827d186a8102005ce41e1ba/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:11847b53d722050808926e785df837353bd4d75f1d494377e59b23594d834967", size = 229382 }, - { url = "https://files.pythonhosted.org/packages/95/a3/c8fb25aac55bf5e12dae5c5aa6a98f85d436c1dc658f21c3ac73f9fa95e5/frozenlist-1.8.0-cp311-cp311-win32.whl", hash = "sha256:27c6e8077956cf73eadd514be8fb04d77fc946a7fe9f7fe167648b0b9085cc25", size = 39647 }, - { url = "https://files.pythonhosted.org/packages/0a/f5/603d0d6a02cfd4c8f2a095a54672b3cf967ad688a60fb9faf04fc4887f65/frozenlist-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:ac913f8403b36a2c8610bbfd25b8013488533e71e62b4b4adce9c86c8cea905b", size = 44064 }, - { url = "https://files.pythonhosted.org/packages/5d/16/c2c9ab44e181f043a86f9a8f84d5124b62dbcb3a02c0977ec72b9ac1d3e0/frozenlist-1.8.0-cp311-cp311-win_arm64.whl", hash = "sha256:d4d3214a0f8394edfa3e303136d0575eece0745ff2b47bd2cb2e66dd92d4351a", size = 39937 }, - { url = "https://files.pythonhosted.org/packages/69/29/948b9aa87e75820a38650af445d2ef2b6b8a6fab1a23b6bb9e4ef0be2d59/frozenlist-1.8.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:78f7b9e5d6f2fdb88cdde9440dc147259b62b9d3b019924def9f6478be254ac1", size = 87782 }, - { url = "https://files.pythonhosted.org/packages/64/80/4f6e318ee2a7c0750ed724fa33a4bdf1eacdc5a39a7a24e818a773cd91af/frozenlist-1.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:229bf37d2e4acdaf808fd3f06e854a4a7a3661e871b10dc1f8f1896a3b05f18b", size = 50594 }, - { url = "https://files.pythonhosted.org/packages/2b/94/5c8a2b50a496b11dd519f4a24cb5496cf125681dd99e94c604ccdea9419a/frozenlist-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f833670942247a14eafbb675458b4e61c82e002a148f49e68257b79296e865c4", size = 50448 }, - { url = "https://files.pythonhosted.org/packages/6a/bd/d91c5e39f490a49df14320f4e8c80161cfcce09f1e2cde1edd16a551abb3/frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:494a5952b1c597ba44e0e78113a7266e656b9794eec897b19ead706bd7074383", size = 242411 }, - { url = "https://files.pythonhosted.org/packages/8f/83/f61505a05109ef3293dfb1ff594d13d64a2324ac3482be2cedc2be818256/frozenlist-1.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96f423a119f4777a4a056b66ce11527366a8bb92f54e541ade21f2374433f6d4", size = 243014 }, - { url = "https://files.pythonhosted.org/packages/d8/cb/cb6c7b0f7d4023ddda30cf56b8b17494eb3a79e3fda666bf735f63118b35/frozenlist-1.8.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3462dd9475af2025c31cc61be6652dfa25cbfb56cbbf52f4ccfe029f38decaf8", size = 234909 }, - { url = "https://files.pythonhosted.org/packages/31/c5/cd7a1f3b8b34af009fb17d4123c5a778b44ae2804e3ad6b86204255f9ec5/frozenlist-1.8.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4c800524c9cd9bac5166cd6f55285957fcfc907db323e193f2afcd4d9abd69b", size = 250049 }, - { url = "https://files.pythonhosted.org/packages/c0/01/2f95d3b416c584a1e7f0e1d6d31998c4a795f7544069ee2e0962a4b60740/frozenlist-1.8.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d6a5df73acd3399d893dafc71663ad22534b5aa4f94e8a2fabfe856c3c1b6a52", size = 256485 }, - { url = "https://files.pythonhosted.org/packages/ce/03/024bf7720b3abaebcff6d0793d73c154237b85bdf67b7ed55e5e9596dc9a/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:405e8fe955c2280ce66428b3ca55e12b3c4e9c336fb2103a4937e891c69a4a29", size = 237619 }, - { url = "https://files.pythonhosted.org/packages/69/fa/f8abdfe7d76b731f5d8bd217827cf6764d4f1d9763407e42717b4bed50a0/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:908bd3f6439f2fef9e85031b59fd4f1297af54415fb60e4254a95f75b3cab3f3", size = 250320 }, - { url = "https://files.pythonhosted.org/packages/f5/3c/b051329f718b463b22613e269ad72138cc256c540f78a6de89452803a47d/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:294e487f9ec720bd8ffcebc99d575f7eff3568a08a253d1ee1a0378754b74143", size = 246820 }, - { url = "https://files.pythonhosted.org/packages/0f/ae/58282e8f98e444b3f4dd42448ff36fa38bef29e40d40f330b22e7108f565/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:74c51543498289c0c43656701be6b077f4b265868fa7f8a8859c197006efb608", size = 250518 }, - { url = "https://files.pythonhosted.org/packages/8f/96/007e5944694d66123183845a106547a15944fbbb7154788cbf7272789536/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:776f352e8329135506a1d6bf16ac3f87bc25b28e765949282dcc627af36123aa", size = 239096 }, - { url = "https://files.pythonhosted.org/packages/66/bb/852b9d6db2fa40be96f29c0d1205c306288f0684df8fd26ca1951d461a56/frozenlist-1.8.0-cp312-cp312-win32.whl", hash = "sha256:433403ae80709741ce34038da08511d4a77062aa924baf411ef73d1146e74faf", size = 39985 }, - { url = "https://files.pythonhosted.org/packages/b8/af/38e51a553dd66eb064cdf193841f16f077585d4d28394c2fa6235cb41765/frozenlist-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:34187385b08f866104f0c0617404c8eb08165ab1272e884abc89c112e9c00746", size = 44591 }, - { url = "https://files.pythonhosted.org/packages/a7/06/1dc65480ab147339fecc70797e9c2f69d9cea9cf38934ce08df070fdb9cb/frozenlist-1.8.0-cp312-cp312-win_arm64.whl", hash = "sha256:fe3c58d2f5db5fbd18c2987cba06d51b0529f52bc3a6cdc33d3f4eab725104bd", size = 40102 }, - { url = "https://files.pythonhosted.org/packages/2d/40/0832c31a37d60f60ed79e9dfb5a92e1e2af4f40a16a29abcc7992af9edff/frozenlist-1.8.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8d92f1a84bb12d9e56f818b3a746f3efba93c1b63c8387a73dde655e1e42282a", size = 85717 }, - { url = "https://files.pythonhosted.org/packages/30/ba/b0b3de23f40bc55a7057bd38434e25c34fa48e17f20ee273bbde5e0650f3/frozenlist-1.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96153e77a591c8adc2ee805756c61f59fef4cf4073a9275ee86fe8cba41241f7", size = 49651 }, - { url = "https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f21f00a91358803399890ab167098c131ec2ddd5f8f5fd5fe9c9f2c6fcd91e40", size = 49417 }, - { url = "https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fb30f9626572a76dfe4293c7194a09fb1fe93ba94c7d4f720dfae3b646b45027", size = 234391 }, - { url = "https://files.pythonhosted.org/packages/40/76/c202df58e3acdf12969a7895fd6f3bc016c642e6726aa63bd3025e0fc71c/frozenlist-1.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaa352d7047a31d87dafcacbabe89df0aa506abb5b1b85a2fb91bc3faa02d822", size = 233048 }, - { url = "https://files.pythonhosted.org/packages/f9/c0/8746afb90f17b73ca5979c7a3958116e105ff796e718575175319b5bb4ce/frozenlist-1.8.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:03ae967b4e297f58f8c774c7eabcce57fe3c2434817d4385c50661845a058121", size = 226549 }, - { url = "https://files.pythonhosted.org/packages/7e/eb/4c7eefc718ff72f9b6c4893291abaae5fbc0c82226a32dcd8ef4f7a5dbef/frozenlist-1.8.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f6292f1de555ffcc675941d65fffffb0a5bcd992905015f85d0592201793e0e5", size = 239833 }, - { url = "https://files.pythonhosted.org/packages/c2/4e/e5c02187cf704224f8b21bee886f3d713ca379535f16893233b9d672ea71/frozenlist-1.8.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29548f9b5b5e3460ce7378144c3010363d8035cea44bc0bf02d57f5a685e084e", size = 245363 }, - { url = "https://files.pythonhosted.org/packages/1f/96/cb85ec608464472e82ad37a17f844889c36100eed57bea094518bf270692/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ec3cc8c5d4084591b4237c0a272cc4f50a5b03396a47d9caaf76f5d7b38a4f11", size = 229314 }, - { url = "https://files.pythonhosted.org/packages/5d/6f/4ae69c550e4cee66b57887daeebe006fe985917c01d0fff9caab9883f6d0/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:517279f58009d0b1f2e7c1b130b377a349405da3f7621ed6bfae50b10adf20c1", size = 243365 }, - { url = "https://files.pythonhosted.org/packages/7a/58/afd56de246cf11780a40a2c28dc7cbabbf06337cc8ddb1c780a2d97e88d8/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:db1e72ede2d0d7ccb213f218df6a078a9c09a7de257c2fe8fcef16d5925230b1", size = 237763 }, - { url = "https://files.pythonhosted.org/packages/cb/36/cdfaf6ed42e2644740d4a10452d8e97fa1c062e2a8006e4b09f1b5fd7d63/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b4dec9482a65c54a5044486847b8a66bf10c9cb4926d42927ec4e8fd5db7fed8", size = 240110 }, - { url = "https://files.pythonhosted.org/packages/03/a8/9ea226fbefad669f11b52e864c55f0bd57d3c8d7eb07e9f2e9a0b39502e1/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:21900c48ae04d13d416f0e1e0c4d81f7931f73a9dfa0b7a8746fb2fe7dd970ed", size = 233717 }, - { url = "https://files.pythonhosted.org/packages/1e/0b/1b5531611e83ba7d13ccc9988967ea1b51186af64c42b7a7af465dcc9568/frozenlist-1.8.0-cp313-cp313-win32.whl", hash = "sha256:8b7b94a067d1c504ee0b16def57ad5738701e4ba10cec90529f13fa03c833496", size = 39628 }, - { url = "https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:878be833caa6a3821caf85eb39c5ba92d28e85df26d57afb06b35b2efd937231", size = 43882 }, - { url = "https://files.pythonhosted.org/packages/c1/17/502cd212cbfa96eb1388614fe39a3fc9ab87dbbe042b66f97acb57474834/frozenlist-1.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:44389d135b3ff43ba8cc89ff7f51f5a0bb6b63d829c8300f79a2fe4fe61bcc62", size = 39676 }, - { url = "https://files.pythonhosted.org/packages/d2/5c/3bbfaa920dfab09e76946a5d2833a7cbdf7b9b4a91c714666ac4855b88b4/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:e25ac20a2ef37e91c1b39938b591457666a0fa835c7783c3a8f33ea42870db94", size = 89235 }, - { url = "https://files.pythonhosted.org/packages/d2/d6/f03961ef72166cec1687e84e8925838442b615bd0b8854b54923ce5b7b8a/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07cdca25a91a4386d2e76ad992916a85038a9b97561bf7a3fd12d5d9ce31870c", size = 50742 }, - { url = "https://files.pythonhosted.org/packages/1e/bb/a6d12b7ba4c3337667d0e421f7181c82dda448ce4e7ad7ecd249a16fa806/frozenlist-1.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4e0c11f2cc6717e0a741f84a527c52616140741cd812a50422f83dc31749fb52", size = 51725 }, - { url = "https://files.pythonhosted.org/packages/bc/71/d1fed0ffe2c2ccd70b43714c6cab0f4188f09f8a67a7914a6b46ee30f274/frozenlist-1.8.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b3210649ee28062ea6099cfda39e147fa1bc039583c8ee4481cb7811e2448c51", size = 284533 }, - { url = "https://files.pythonhosted.org/packages/c9/1f/fb1685a7b009d89f9bf78a42d94461bc06581f6e718c39344754a5d9bada/frozenlist-1.8.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:581ef5194c48035a7de2aefc72ac6539823bb71508189e5de01d60c9dcd5fa65", size = 292506 }, - { url = "https://files.pythonhosted.org/packages/e6/3b/b991fe1612703f7e0d05c0cf734c1b77aaf7c7d321df4572e8d36e7048c8/frozenlist-1.8.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3ef2d026f16a2b1866e1d86fc4e1291e1ed8a387b2c333809419a2f8b3a77b82", size = 274161 }, - { url = "https://files.pythonhosted.org/packages/ca/ec/c5c618767bcdf66e88945ec0157d7f6c4a1322f1473392319b7a2501ded7/frozenlist-1.8.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5500ef82073f599ac84d888e3a8c1f77ac831183244bfd7f11eaa0289fb30714", size = 294676 }, - { url = "https://files.pythonhosted.org/packages/7c/ce/3934758637d8f8a88d11f0585d6495ef54b2044ed6ec84492a91fa3b27aa/frozenlist-1.8.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50066c3997d0091c411a66e710f4e11752251e6d2d73d70d8d5d4c76442a199d", size = 300638 }, - { url = "https://files.pythonhosted.org/packages/fc/4f/a7e4d0d467298f42de4b41cbc7ddaf19d3cfeabaf9ff97c20c6c7ee409f9/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:5c1c8e78426e59b3f8005e9b19f6ff46e5845895adbde20ece9218319eca6506", size = 283067 }, - { url = "https://files.pythonhosted.org/packages/dc/48/c7b163063d55a83772b268e6d1affb960771b0e203b632cfe09522d67ea5/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:eefdba20de0d938cec6a89bd4d70f346a03108a19b9df4248d3cf0d88f1b0f51", size = 292101 }, - { url = "https://files.pythonhosted.org/packages/9f/d0/2366d3c4ecdc2fd391e0afa6e11500bfba0ea772764d631bbf82f0136c9d/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cf253e0e1c3ceb4aaff6df637ce033ff6535fb8c70a764a8f46aafd3d6ab798e", size = 289901 }, - { url = "https://files.pythonhosted.org/packages/b8/94/daff920e82c1b70e3618a2ac39fbc01ae3e2ff6124e80739ce5d71c9b920/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:032efa2674356903cd0261c4317a561a6850f3ac864a63fc1583147fb05a79b0", size = 289395 }, - { url = "https://files.pythonhosted.org/packages/e3/20/bba307ab4235a09fdcd3cc5508dbabd17c4634a1af4b96e0f69bfe551ebd/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6da155091429aeba16851ecb10a9104a108bcd32f6c1642867eadaee401c1c41", size = 283659 }, - { url = "https://files.pythonhosted.org/packages/fd/00/04ca1c3a7a124b6de4f8a9a17cc2fcad138b4608e7a3fc5877804b8715d7/frozenlist-1.8.0-cp313-cp313t-win32.whl", hash = "sha256:0f96534f8bfebc1a394209427d0f8a63d343c9779cda6fc25e8e121b5fd8555b", size = 43492 }, - { url = "https://files.pythonhosted.org/packages/59/5e/c69f733a86a94ab10f68e496dc6b7e8bc078ebb415281d5698313e3af3a1/frozenlist-1.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5d63a068f978fc69421fb0e6eb91a9603187527c86b7cd3f534a5b77a592b888", size = 48034 }, - { url = "https://files.pythonhosted.org/packages/16/6c/be9d79775d8abe79b05fa6d23da99ad6e7763a1d080fbae7290b286093fd/frozenlist-1.8.0-cp313-cp313t-win_arm64.whl", hash = "sha256:bf0a7e10b077bf5fb9380ad3ae8ce20ef919a6ad93b4552896419ac7e1d8e042", size = 41749 }, - { url = "https://files.pythonhosted.org/packages/f1/c8/85da824b7e7b9b6e7f7705b2ecaf9591ba6f79c1177f324c2735e41d36a2/frozenlist-1.8.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cee686f1f4cadeb2136007ddedd0aaf928ab95216e7691c63e50a8ec066336d0", size = 86127 }, - { url = "https://files.pythonhosted.org/packages/8e/e8/a1185e236ec66c20afd72399522f142c3724c785789255202d27ae992818/frozenlist-1.8.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:119fb2a1bd47307e899c2fac7f28e85b9a543864df47aa7ec9d3c1b4545f096f", size = 49698 }, - { url = "https://files.pythonhosted.org/packages/a1/93/72b1736d68f03fda5fdf0f2180fb6caaae3894f1b854d006ac61ecc727ee/frozenlist-1.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4970ece02dbc8c3a92fcc5228e36a3e933a01a999f7094ff7c23fbd2beeaa67c", size = 49749 }, - { url = "https://files.pythonhosted.org/packages/a7/b2/fabede9fafd976b991e9f1b9c8c873ed86f202889b864756f240ce6dd855/frozenlist-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2", size = 231298 }, - { url = "https://files.pythonhosted.org/packages/3a/3b/d9b1e0b0eed36e70477ffb8360c49c85c8ca8ef9700a4e6711f39a6e8b45/frozenlist-1.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:778a11b15673f6f1df23d9586f83c4846c471a8af693a22e066508b77d201ec8", size = 232015 }, - { url = "https://files.pythonhosted.org/packages/dc/94/be719d2766c1138148564a3960fc2c06eb688da592bdc25adcf856101be7/frozenlist-1.8.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686", size = 225038 }, - { url = "https://files.pythonhosted.org/packages/e4/09/6712b6c5465f083f52f50cf74167b92d4ea2f50e46a9eea0523d658454ae/frozenlist-1.8.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:97260ff46b207a82a7567b581ab4190bd4dfa09f4db8a8b49d1a958f6aa4940e", size = 240130 }, - { url = "https://files.pythonhosted.org/packages/f8/d4/cd065cdcf21550b54f3ce6a22e143ac9e4836ca42a0de1022da8498eac89/frozenlist-1.8.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:54b2077180eb7f83dd52c40b2750d0a9f175e06a42e3213ce047219de902717a", size = 242845 }, - { url = "https://files.pythonhosted.org/packages/62/c3/f57a5c8c70cd1ead3d5d5f776f89d33110b1addae0ab010ad774d9a44fb9/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2f05983daecab868a31e1da44462873306d3cbfd76d1f0b5b69c473d21dbb128", size = 229131 }, - { url = "https://files.pythonhosted.org/packages/6c/52/232476fe9cb64f0742f3fde2b7d26c1dac18b6d62071c74d4ded55e0ef94/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:33f48f51a446114bc5d251fb2954ab0164d5be02ad3382abcbfe07e2531d650f", size = 240542 }, - { url = "https://files.pythonhosted.org/packages/5f/85/07bf3f5d0fb5414aee5f47d33c6f5c77bfe49aac680bfece33d4fdf6a246/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:154e55ec0655291b5dd1b8731c637ecdb50975a2ae70c606d100750a540082f7", size = 237308 }, - { url = "https://files.pythonhosted.org/packages/11/99/ae3a33d5befd41ac0ca2cc7fd3aa707c9c324de2e89db0e0f45db9a64c26/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:4314debad13beb564b708b4a496020e5306c7333fa9a3ab90374169a20ffab30", size = 238210 }, - { url = "https://files.pythonhosted.org/packages/b2/60/b1d2da22f4970e7a155f0adde9b1435712ece01b3cd45ba63702aea33938/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:073f8bf8becba60aa931eb3bc420b217bb7d5b8f4750e6f8b3be7f3da85d38b7", size = 231972 }, - { url = "https://files.pythonhosted.org/packages/3f/ab/945b2f32de889993b9c9133216c068b7fcf257d8595a0ac420ac8677cab0/frozenlist-1.8.0-cp314-cp314-win32.whl", hash = "sha256:bac9c42ba2ac65ddc115d930c78d24ab8d4f465fd3fc473cdedfccadb9429806", size = 40536 }, - { url = "https://files.pythonhosted.org/packages/59/ad/9caa9b9c836d9ad6f067157a531ac48b7d36499f5036d4141ce78c230b1b/frozenlist-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:3e0761f4d1a44f1d1a47996511752cf3dcec5bbdd9cc2b4fe595caf97754b7a0", size = 44330 }, - { url = "https://files.pythonhosted.org/packages/82/13/e6950121764f2676f43534c555249f57030150260aee9dcf7d64efda11dd/frozenlist-1.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:d1eaff1d00c7751b7c6662e9c5ba6eb2c17a2306ba5e2a37f24ddf3cc953402b", size = 40627 }, - { url = "https://files.pythonhosted.org/packages/c0/c7/43200656ecc4e02d3f8bc248df68256cd9572b3f0017f0a0c4e93440ae23/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d3bb933317c52d7ea5004a1c442eef86f426886fba134ef8cf4226ea6ee1821d", size = 89238 }, - { url = "https://files.pythonhosted.org/packages/d1/29/55c5f0689b9c0fb765055629f472c0de484dcaf0acee2f7707266ae3583c/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8009897cdef112072f93a0efdce29cd819e717fd2f649ee3016efd3cd885a7ed", size = 50738 }, - { url = "https://files.pythonhosted.org/packages/ba/7d/b7282a445956506fa11da8c2db7d276adcbf2b17d8bb8407a47685263f90/frozenlist-1.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2c5dcbbc55383e5883246d11fd179782a9d07a986c40f49abe89ddf865913930", size = 51739 }, - { url = "https://files.pythonhosted.org/packages/62/1c/3d8622e60d0b767a5510d1d3cf21065b9db874696a51ea6d7a43180a259c/frozenlist-1.8.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:39ecbc32f1390387d2aa4f5a995e465e9e2f79ba3adcac92d68e3e0afae6657c", size = 284186 }, - { url = "https://files.pythonhosted.org/packages/2d/14/aa36d5f85a89679a85a1d44cd7a6657e0b1c75f61e7cad987b203d2daca8/frozenlist-1.8.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92db2bf818d5cc8d9c1f1fc56b897662e24ea5adb36ad1f1d82875bd64e03c24", size = 292196 }, - { url = "https://files.pythonhosted.org/packages/05/23/6bde59eb55abd407d34f77d39a5126fb7b4f109a3f611d3929f14b700c66/frozenlist-1.8.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2dc43a022e555de94c3b68a4ef0b11c4f747d12c024a520c7101709a2144fb37", size = 273830 }, - { url = "https://files.pythonhosted.org/packages/d2/3f/22cff331bfad7a8afa616289000ba793347fcd7bc275f3b28ecea2a27909/frozenlist-1.8.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb89a7f2de3602cfed448095bab3f178399646ab7c61454315089787df07733a", size = 294289 }, - { url = "https://files.pythonhosted.org/packages/a4/89/5b057c799de4838b6c69aa82b79705f2027615e01be996d2486a69ca99c4/frozenlist-1.8.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:33139dc858c580ea50e7e60a1b0ea003efa1fd42e6ec7fdbad78fff65fad2fd2", size = 300318 }, - { url = "https://files.pythonhosted.org/packages/30/de/2c22ab3eb2a8af6d69dc799e48455813bab3690c760de58e1bf43b36da3e/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:168c0969a329b416119507ba30b9ea13688fafffac1b7822802537569a1cb0ef", size = 282814 }, - { url = "https://files.pythonhosted.org/packages/59/f7/970141a6a8dbd7f556d94977858cfb36fa9b66e0892c6dd780d2219d8cd8/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:28bd570e8e189d7f7b001966435f9dac6718324b5be2990ac496cf1ea9ddb7fe", size = 291762 }, - { url = "https://files.pythonhosted.org/packages/c1/15/ca1adae83a719f82df9116d66f5bb28bb95557b3951903d39135620ef157/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b2a095d45c5d46e5e79ba1e5b9cb787f541a8dee0433836cea4b96a2c439dcd8", size = 289470 }, - { url = "https://files.pythonhosted.org/packages/ac/83/dca6dc53bf657d371fbc88ddeb21b79891e747189c5de990b9dfff2ccba1/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:eab8145831a0d56ec9c4139b6c3e594c7a83c2c8be25d5bcf2d86136a532287a", size = 289042 }, - { url = "https://files.pythonhosted.org/packages/96/52/abddd34ca99be142f354398700536c5bd315880ed0a213812bc491cff5e4/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:974b28cf63cc99dfb2188d8d222bc6843656188164848c4f679e63dae4b0708e", size = 283148 }, - { url = "https://files.pythonhosted.org/packages/af/d3/76bd4ed4317e7119c2b7f57c3f6934aba26d277acc6309f873341640e21f/frozenlist-1.8.0-cp314-cp314t-win32.whl", hash = "sha256:342c97bf697ac5480c0a7ec73cd700ecfa5a8a40ac923bd035484616efecc2df", size = 44676 }, - { url = "https://files.pythonhosted.org/packages/89/76/c615883b7b521ead2944bb3480398cbb07e12b7b4e4d073d3752eb721558/frozenlist-1.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:06be8f67f39c8b1dc671f5d83aaefd3358ae5cdcf8314552c57e7ed3e6475bdd", size = 49451 }, - { url = "https://files.pythonhosted.org/packages/e0/a3/5982da14e113d07b325230f95060e2169f5311b1017ea8af2a29b374c289/frozenlist-1.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:102e6314ca4da683dca92e3b1355490fed5f313b768500084fbe6371fddfdb79", size = 42507 }, - { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409 }, -] - [[package]] name = "fsspec" version = "2025.9.0" @@ -711,11 +397,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/47/71/70db47e4f6ce3e5c37a607355f80da8860a33226be640226ac52cb05ef2e/fsspec-2025.9.0-py3-none-any.whl", hash = "sha256:530dc2a2af60a414a832059574df4a6e10cce927f6f4a78209390fe38955cfb7", size = 199289 }, ] -[package.optional-dependencies] -http = [ - { name = "aiohttp" }, -] - [[package]] name = "h11" version = "0.16.0" @@ -819,52 +500,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484 }, ] -[[package]] -name = "ipython" -version = "9.6.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "decorator" }, - { name = "ipython-pygments-lexers" }, - { name = "jedi" }, - { name = "matplotlib-inline" }, - { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, - { name = "prompt-toolkit" }, - { name = "pygments" }, - { name = "stack-data" }, - { name = "traitlets" }, - { name = "typing-extensions", marker = "python_full_version < '3.12'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/2a/34/29b18c62e39ee2f7a6a3bba7efd952729d8aadd45ca17efc34453b717665/ipython-9.6.0.tar.gz", hash = "sha256:5603d6d5d356378be5043e69441a072b50a5b33b4503428c77b04cb8ce7bc731", size = 4396932 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/48/c5/d5e07995077e48220269c28a221e168c91123ad5ceee44d548f54a057fc0/ipython-9.6.0-py3-none-any.whl", hash = "sha256:5f77efafc886d2f023442479b8149e7d86547ad0a979e9da9f045d252f648196", size = 616170 }, -] - -[[package]] -name = "ipython-pygments-lexers" -version = "1.1.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pygments" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c", size = 8074 }, -] - -[[package]] -name = "jedi" -version = "0.19.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "parso" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/72/3a/79a912fbd4d8dd6fbb02bf69afd3bb72cf0c729bb3063c6f4498603db17a/jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0", size = 1231287 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278 }, -] - [[package]] name = "jinja2" version = "3.1.6" @@ -972,12 +607,24 @@ wheels = [ ] [[package]] -name = "jsonpickle" -version = "4.1.1" +name = "jsonpatch" +version = "1.33" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e4/a6/d07afcfdef402900229bcca795f80506b207af13a838d4d99ad45abf530c/jsonpickle-4.1.1.tar.gz", hash = "sha256:f86e18f13e2b96c1c1eede0b7b90095bbb61d99fedc14813c44dc2f361dbbae1", size = 316885 } +dependencies = [ + { name = "jsonpointer" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/78/18813351fe5d63acad16aec57f94ec2b70a09e53ca98145589e185423873/jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c", size = 21699 } wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/73/04df8a6fa66d43a9fd45c30f283cc4afff17da671886e451d52af60bdc7e/jsonpickle-4.1.1-py3-none-any.whl", hash = "sha256:bb141da6057898aa2438ff268362b126826c812a1721e31cf08a6e142910dc91", size = 47125 }, + { url = "https://files.pythonhosted.org/packages/73/07/02e16ed01e04a374e644b575638ec7987ae846d25ad97bcc9945a3ee4b0e/jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade", size = 12898 }, +] + +[[package]] +name = "jsonpointer" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/0a/eebeb1fa92507ea94016a2a790b93c2ae41a7e18778f85471dc54475ed25/jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef", size = 9114 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942", size = 7595 }, ] [[package]] @@ -1070,6 +717,36 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/da/e9/0d4add7873a73e462aeb45c036a2dead2562b825aa46ba326727b3f31016/kiwisolver-1.4.9-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:fb940820c63a9590d31d88b815e7a3aa5915cad3ce735ab45f0c730b39547de1", size = 73929 }, ] +[[package]] +name = "langchain-core" +version = "1.0.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jsonpatch" }, + { name = "langsmith" }, + { name = "packaging" }, + { name = "pydantic" }, + { name = "pyyaml" }, + { name = "tenacity" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b4/96/b298cb46643bb235240de7ec8d87d3b4ccefead6bf41ca3c48c7d5397e01/langchain_core-1.0.2.tar.gz", hash = "sha256:9aae1908cc00d50b88e812305e980e7fd06d07375590ce8da01c04037bdccd72", size = 769167 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/52/54/3aed89938a42cf7115575c333647551e35adc380feed651105d2d86c22f5/langchain_core-1.0.2-py3-none-any.whl", hash = "sha256:1f4ab4a41fc2e135e5dd4b97a89af123bbdc535af8f1f0644e8e8801bc288a12", size = 469251 }, +] + +[[package]] +name = "langchain-text-splitters" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "langchain-core" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fa/2e/c833dcc379c1c086453708ef5eef7d4d1f808559ca4458bd6569d5d83ad7/langchain_text_splitters-1.0.0.tar.gz", hash = "sha256:d8580a20ad7ed10b432feb273e5758b2cc0902d094919629cec0e1ad691a6744", size = 264257 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/97/d362353ab04f865af6f81d4d46e7aa428734aa032de0017934b771fc34b7/langchain_text_splitters-1.0.0-py3-none-any.whl", hash = "sha256:f00c8219d3468f2c5bd951b708b6a7dd9bc3c62d0cfb83124c377f7170f33b2e", size = 33851 }, +] + [[package]] name = "langcodes" version = "3.5.0" @@ -1082,6 +759,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c3/6b/068c2ea7a712bf805c62445bd9e9c06d7340358ef2824150eceac027444b/langcodes-3.5.0-py3-none-any.whl", hash = "sha256:853c69d1a35e0e13da2f427bb68fb2fa4a8f4fb899e0c62ad8df8d073dcfed33", size = 182974 }, ] +[[package]] +name = "langsmith" +version = "0.4.38" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "httpx" }, + { name = "orjson", marker = "platform_python_implementation != 'PyPy'" }, + { name = "packaging" }, + { name = "pydantic" }, + { name = "requests" }, + { name = "requests-toolbelt" }, + { name = "zstandard" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/37/21/f1ba48412c64bf3bb8feb532fc9d247b396935b5d8242332d44a4195ec2d/langsmith-0.4.38.tar.gz", hash = "sha256:3aa57f9c16a5880256cd1eab0452533c1fb5ee14ec5250e23ed919cc2b07f6d3", size = 942789 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b4/2b/7e0248f65e35800ea8e4e3dbb3bcc36c61b81f5b8abeddaceec8320ab491/langsmith-0.4.38-py3-none-any.whl", hash = "sha256:326232a24b1c6dd308a3188557cc023adf8fb14144263b2982c115a6be5141e7", size = 397341 }, +] + [[package]] name = "language-data" version = "1.3.0" @@ -1300,18 +995,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9a/cc/3fe688ff1355010937713164caacf9ed443675ac48a997bab6ed23b3f7c0/matplotlib-3.10.7-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3886e47f64611046bc1db523a09dd0a0a6bed6081e6f90e13806dd1d1d1b5e91", size = 8693919 }, ] -[[package]] -name = "matplotlib-inline" -version = "0.2.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "traitlets" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/c7/74/97e72a36efd4ae2bccb3463284300f8953f199b5ffbc04cbbb0ec78f74b1/matplotlib_inline-0.2.1.tar.gz", hash = "sha256:e1ee949c340d771fc39e241ea75683deb94762c8fa5f2927ec57c83c4dffa9fe", size = 8110 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/af/33/ee4519fa02ed11a94aef9559552f3b17bb863f2ecfe1a35dc7f548cde231/matplotlib_inline-0.2.1-py3-none-any.whl", hash = "sha256:d56ce5156ba6085e00a9d54fead6ed29a9c47e215cd1bba2e976ef39f5710a76", size = 9516 }, -] - [[package]] name = "mdurl" version = "0.1.2" @@ -1326,7 +1009,7 @@ name = "memory-poc" version = "0.1.0" source = { virtual = "." } dependencies = [ - { name = "fastcoref" }, + { name = "langchain-text-splitters" }, { name = "matplotlib" }, { name = "networkx" }, { name = "nltk" }, @@ -1337,7 +1020,6 @@ dependencies = [ { name = "pytest" }, { name = "pytest-asyncio" }, { name = "python-dotenv" }, - { name = "pyvis" }, { name = "rich" }, { name = "sentence-transformers" }, { name = "spacy" }, @@ -1346,7 +1028,7 @@ dependencies = [ [package.metadata] requires-dist = [ - { name = "fastcoref", specifier = ">=2.1.0" }, + { name = "langchain-text-splitters", specifier = ">=0.3.0" }, { name = "matplotlib", specifier = ">=3.7.0" }, { name = "networkx", specifier = ">=3.0" }, { name = "nltk", specifier = ">=3.8.0" }, @@ -1357,7 +1039,6 @@ requires-dist = [ { name = "pytest", specifier = ">=7.0.0" }, { name = "pytest-asyncio", specifier = ">=0.21.0" }, { name = "python-dotenv", specifier = ">=1.0.0" }, - { name = "pyvis", specifier = ">=0.3.0" }, { name = "rich", specifier = ">=13.0.0" }, { name = "sentence-transformers", specifier = ">=2.2.0" }, { name = "spacy", specifier = ">=3.7.0" }, @@ -1373,139 +1054,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198 }, ] -[[package]] -name = "multidict" -version = "6.7.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/80/1e/5492c365f222f907de1039b91f922b93fa4f764c713ee858d235495d8f50/multidict-6.7.0.tar.gz", hash = "sha256:c6e99d9a65ca282e578dfea819cfa9c0a62b2499d8677392e09feaf305e9e6f5", size = 101834 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/34/9e/5c727587644d67b2ed479041e4b1c58e30afc011e3d45d25bbe35781217c/multidict-6.7.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4d409aa42a94c0b3fa617708ef5276dfe81012ba6753a0370fcc9d0195d0a1fc", size = 76604 }, - { url = "https://files.pythonhosted.org/packages/17/e4/67b5c27bd17c085a5ea8f1ec05b8a3e5cba0ca734bfcad5560fb129e70ca/multidict-6.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:14c9e076eede3b54c636f8ce1c9c252b5f057c62131211f0ceeec273810c9721", size = 44715 }, - { url = "https://files.pythonhosted.org/packages/4d/e1/866a5d77be6ea435711bef2a4291eed11032679b6b28b56b4776ab06ba3e/multidict-6.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4c09703000a9d0fa3c3404b27041e574cc7f4df4c6563873246d0e11812a94b6", size = 44332 }, - { url = "https://files.pythonhosted.org/packages/31/61/0c2d50241ada71ff61a79518db85ada85fdabfcf395d5968dae1cbda04e5/multidict-6.7.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a265acbb7bb33a3a2d626afbe756371dce0279e7b17f4f4eda406459c2b5ff1c", size = 245212 }, - { url = "https://files.pythonhosted.org/packages/ac/e0/919666a4e4b57fff1b57f279be1c9316e6cdc5de8a8b525d76f6598fefc7/multidict-6.7.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:51cb455de290ae462593e5b1cb1118c5c22ea7f0d3620d9940bf695cea5a4bd7", size = 246671 }, - { url = "https://files.pythonhosted.org/packages/a1/cc/d027d9c5a520f3321b65adea289b965e7bcbd2c34402663f482648c716ce/multidict-6.7.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:db99677b4457c7a5c5a949353e125ba72d62b35f74e26da141530fbb012218a7", size = 225491 }, - { url = "https://files.pythonhosted.org/packages/75/c4/bbd633980ce6155a28ff04e6a6492dd3335858394d7bb752d8b108708558/multidict-6.7.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f470f68adc395e0183b92a2f4689264d1ea4b40504a24d9882c27375e6662bb9", size = 257322 }, - { url = "https://files.pythonhosted.org/packages/4c/6d/d622322d344f1f053eae47e033b0b3f965af01212de21b10bcf91be991fb/multidict-6.7.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0db4956f82723cc1c270de9c6e799b4c341d327762ec78ef82bb962f79cc07d8", size = 254694 }, - { url = "https://files.pythonhosted.org/packages/a8/9f/78f8761c2705d4c6d7516faed63c0ebdac569f6db1bef95e0d5218fdc146/multidict-6.7.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3e56d780c238f9e1ae66a22d2adf8d16f485381878250db8d496623cd38b22bd", size = 246715 }, - { url = "https://files.pythonhosted.org/packages/78/59/950818e04f91b9c2b95aab3d923d9eabd01689d0dcd889563988e9ea0fd8/multidict-6.7.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9d14baca2ee12c1a64740d4531356ba50b82543017f3ad6de0deb943c5979abb", size = 243189 }, - { url = "https://files.pythonhosted.org/packages/7a/3d/77c79e1934cad2ee74991840f8a0110966d9599b3af95964c0cd79bb905b/multidict-6.7.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:295a92a76188917c7f99cda95858c822f9e4aae5824246bba9b6b44004ddd0a6", size = 237845 }, - { url = "https://files.pythonhosted.org/packages/63/1b/834ce32a0a97a3b70f86437f685f880136677ac00d8bce0027e9fd9c2db7/multidict-6.7.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39f1719f57adbb767ef592a50ae5ebb794220d1188f9ca93de471336401c34d2", size = 246374 }, - { url = "https://files.pythonhosted.org/packages/23/ef/43d1c3ba205b5dec93dc97f3fba179dfa47910fc73aaaea4f7ceb41cec2a/multidict-6.7.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:0a13fb8e748dfc94749f622de065dd5c1def7e0d2216dba72b1d8069a389c6ff", size = 253345 }, - { url = "https://files.pythonhosted.org/packages/6b/03/eaf95bcc2d19ead522001f6a650ef32811aa9e3624ff0ad37c445c7a588c/multidict-6.7.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e3aa16de190d29a0ea1b48253c57d99a68492c8dd8948638073ab9e74dc9410b", size = 246940 }, - { url = "https://files.pythonhosted.org/packages/e8/df/ec8a5fd66ea6cd6f525b1fcbb23511b033c3e9bc42b81384834ffa484a62/multidict-6.7.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a048ce45dcdaaf1defb76b2e684f997fb5abf74437b6cb7b22ddad934a964e34", size = 242229 }, - { url = "https://files.pythonhosted.org/packages/8a/a2/59b405d59fd39ec86d1142630e9049243015a5f5291ba49cadf3c090c541/multidict-6.7.0-cp311-cp311-win32.whl", hash = "sha256:a90af66facec4cebe4181b9e62a68be65e45ac9b52b67de9eec118701856e7ff", size = 41308 }, - { url = "https://files.pythonhosted.org/packages/32/0f/13228f26f8b882c34da36efa776c3b7348455ec383bab4a66390e42963ae/multidict-6.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:95b5ffa4349df2887518bb839409bcf22caa72d82beec453216802f475b23c81", size = 46037 }, - { url = "https://files.pythonhosted.org/packages/84/1f/68588e31b000535a3207fd3c909ebeec4fb36b52c442107499c18a896a2a/multidict-6.7.0-cp311-cp311-win_arm64.whl", hash = "sha256:329aa225b085b6f004a4955271a7ba9f1087e39dcb7e65f6284a988264a63912", size = 43023 }, - { url = "https://files.pythonhosted.org/packages/c2/9e/9f61ac18d9c8b475889f32ccfa91c9f59363480613fc807b6e3023d6f60b/multidict-6.7.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8a3862568a36d26e650a19bb5cbbba14b71789032aebc0423f8cc5f150730184", size = 76877 }, - { url = "https://files.pythonhosted.org/packages/38/6f/614f09a04e6184f8824268fce4bc925e9849edfa654ddd59f0b64508c595/multidict-6.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:960c60b5849b9b4f9dcc9bea6e3626143c252c74113df2c1540aebce70209b45", size = 45467 }, - { url = "https://files.pythonhosted.org/packages/b3/93/c4f67a436dd026f2e780c433277fff72be79152894d9fc36f44569cab1a6/multidict-6.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2049be98fb57a31b4ccf870bf377af2504d4ae35646a19037ec271e4c07998aa", size = 43834 }, - { url = "https://files.pythonhosted.org/packages/7f/f5/013798161ca665e4a422afbc5e2d9e4070142a9ff8905e482139cd09e4d0/multidict-6.7.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0934f3843a1860dd465d38895c17fce1f1cb37295149ab05cd1b9a03afacb2a7", size = 250545 }, - { url = "https://files.pythonhosted.org/packages/71/2f/91dbac13e0ba94669ea5119ba267c9a832f0cb65419aca75549fcf09a3dc/multidict-6.7.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b3e34f3a1b8131ba06f1a73adab24f30934d148afcd5f5de9a73565a4404384e", size = 258305 }, - { url = "https://files.pythonhosted.org/packages/ef/b0/754038b26f6e04488b48ac621f779c341338d78503fb45403755af2df477/multidict-6.7.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:efbb54e98446892590dc2458c19c10344ee9a883a79b5cec4bc34d6656e8d546", size = 242363 }, - { url = "https://files.pythonhosted.org/packages/87/15/9da40b9336a7c9fa606c4cf2ed80a649dffeb42b905d4f63a1d7eb17d746/multidict-6.7.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a35c5fc61d4f51eb045061e7967cfe3123d622cd500e8868e7c0c592a09fedc4", size = 268375 }, - { url = "https://files.pythonhosted.org/packages/82/72/c53fcade0cc94dfaad583105fd92b3a783af2091eddcb41a6d5a52474000/multidict-6.7.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29fe6740ebccba4175af1b9b87bf553e9c15cd5868ee967e010efcf94e4fd0f1", size = 269346 }, - { url = "https://files.pythonhosted.org/packages/0d/e2/9baffdae21a76f77ef8447f1a05a96ec4bc0a24dae08767abc0a2fe680b8/multidict-6.7.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:123e2a72e20537add2f33a79e605f6191fba2afda4cbb876e35c1a7074298a7d", size = 256107 }, - { url = "https://files.pythonhosted.org/packages/3c/06/3f06f611087dc60d65ef775f1fb5aca7c6d61c6db4990e7cda0cef9b1651/multidict-6.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b284e319754366c1aee2267a2036248b24eeb17ecd5dc16022095e747f2f4304", size = 253592 }, - { url = "https://files.pythonhosted.org/packages/20/24/54e804ec7945b6023b340c412ce9c3f81e91b3bf5fa5ce65558740141bee/multidict-6.7.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:803d685de7be4303b5a657b76e2f6d1240e7e0a8aa2968ad5811fa2285553a12", size = 251024 }, - { url = "https://files.pythonhosted.org/packages/14/48/011cba467ea0b17ceb938315d219391d3e421dfd35928e5dbdc3f4ae76ef/multidict-6.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c04a328260dfd5db8c39538f999f02779012268f54614902d0afc775d44e0a62", size = 251484 }, - { url = "https://files.pythonhosted.org/packages/0d/2f/919258b43bb35b99fa127435cfb2d91798eb3a943396631ef43e3720dcf4/multidict-6.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8a19cdb57cd3df4cd865849d93ee14920fb97224300c88501f16ecfa2604b4e0", size = 263579 }, - { url = "https://files.pythonhosted.org/packages/31/22/a0e884d86b5242b5a74cf08e876bdf299e413016b66e55511f7a804a366e/multidict-6.7.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9b2fd74c52accced7e75de26023b7dccee62511a600e62311b918ec5c168fc2a", size = 259654 }, - { url = "https://files.pythonhosted.org/packages/b2/e5/17e10e1b5c5f5a40f2fcbb45953c9b215f8a4098003915e46a93f5fcaa8f/multidict-6.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3e8bfdd0e487acf992407a140d2589fe598238eaeffa3da8448d63a63cd363f8", size = 251511 }, - { url = "https://files.pythonhosted.org/packages/e3/9a/201bb1e17e7af53139597069c375e7b0dcbd47594604f65c2d5359508566/multidict-6.7.0-cp312-cp312-win32.whl", hash = "sha256:dd32a49400a2c3d52088e120ee00c1e3576cbff7e10b98467962c74fdb762ed4", size = 41895 }, - { url = "https://files.pythonhosted.org/packages/46/e2/348cd32faad84eaf1d20cce80e2bb0ef8d312c55bca1f7fa9865e7770aaf/multidict-6.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:92abb658ef2d7ef22ac9f8bb88e8b6c3e571671534e029359b6d9e845923eb1b", size = 46073 }, - { url = "https://files.pythonhosted.org/packages/25/ec/aad2613c1910dce907480e0c3aa306905830f25df2e54ccc9dea450cb5aa/multidict-6.7.0-cp312-cp312-win_arm64.whl", hash = "sha256:490dab541a6a642ce1a9d61a4781656b346a55c13038f0b1244653828e3a83ec", size = 43226 }, - { url = "https://files.pythonhosted.org/packages/d2/86/33272a544eeb36d66e4d9a920602d1a2f57d4ebea4ef3cdfe5a912574c95/multidict-6.7.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bee7c0588aa0076ce77c0ea5d19a68d76ad81fcd9fe8501003b9a24f9d4000f6", size = 76135 }, - { url = "https://files.pythonhosted.org/packages/91/1c/eb97db117a1ebe46d457a3d235a7b9d2e6dcab174f42d1b67663dd9e5371/multidict-6.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7ef6b61cad77091056ce0e7ce69814ef72afacb150b7ac6a3e9470def2198159", size = 45117 }, - { url = "https://files.pythonhosted.org/packages/f1/d8/6c3442322e41fb1dd4de8bd67bfd11cd72352ac131f6368315617de752f1/multidict-6.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9c0359b1ec12b1d6849c59f9d319610b7f20ef990a6d454ab151aa0e3b9f78ca", size = 43472 }, - { url = "https://files.pythonhosted.org/packages/75/3f/e2639e80325af0b6c6febdf8e57cc07043ff15f57fa1ef808f4ccb5ac4cd/multidict-6.7.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cd240939f71c64bd658f186330603aac1a9a81bf6273f523fca63673cb7378a8", size = 249342 }, - { url = "https://files.pythonhosted.org/packages/5d/cc/84e0585f805cbeaa9cbdaa95f9a3d6aed745b9d25700623ac89a6ecff400/multidict-6.7.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a60a4d75718a5efa473ebd5ab685786ba0c67b8381f781d1be14da49f1a2dc60", size = 257082 }, - { url = "https://files.pythonhosted.org/packages/b0/9c/ac851c107c92289acbbf5cfb485694084690c1b17e555f44952c26ddc5bd/multidict-6.7.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53a42d364f323275126aff81fb67c5ca1b7a04fda0546245730a55c8c5f24bc4", size = 240704 }, - { url = "https://files.pythonhosted.org/packages/50/cc/5f93e99427248c09da95b62d64b25748a5f5c98c7c2ab09825a1d6af0e15/multidict-6.7.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3b29b980d0ddbecb736735ee5bef69bb2ddca56eff603c86f3f29a1128299b4f", size = 266355 }, - { url = "https://files.pythonhosted.org/packages/ec/0c/2ec1d883ceb79c6f7f6d7ad90c919c898f5d1c6ea96d322751420211e072/multidict-6.7.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f8a93b1c0ed2d04b97a5e9336fd2d33371b9a6e29ab7dd6503d63407c20ffbaf", size = 267259 }, - { url = "https://files.pythonhosted.org/packages/c6/2d/f0b184fa88d6630aa267680bdb8623fb69cb0d024b8c6f0d23f9a0f406d3/multidict-6.7.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9ff96e8815eecacc6645da76c413eb3b3d34cfca256c70b16b286a687d013c32", size = 254903 }, - { url = "https://files.pythonhosted.org/packages/06/c9/11ea263ad0df7dfabcad404feb3c0dd40b131bc7f232d5537f2fb1356951/multidict-6.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7516c579652f6a6be0e266aec0acd0db80829ca305c3d771ed898538804c2036", size = 252365 }, - { url = "https://files.pythonhosted.org/packages/41/88/d714b86ee2c17d6e09850c70c9d310abac3d808ab49dfa16b43aba9d53fd/multidict-6.7.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:040f393368e63fb0f3330e70c26bfd336656bed925e5cbe17c9da839a6ab13ec", size = 250062 }, - { url = "https://files.pythonhosted.org/packages/15/fe/ad407bb9e818c2b31383f6131ca19ea7e35ce93cf1310fce69f12e89de75/multidict-6.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b3bc26a951007b1057a1c543af845f1c7e3e71cc240ed1ace7bf4484aa99196e", size = 249683 }, - { url = "https://files.pythonhosted.org/packages/8c/a4/a89abdb0229e533fb925e7c6e5c40201c2873efebc9abaf14046a4536ee6/multidict-6.7.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7b022717c748dd1992a83e219587aabe45980d88969f01b316e78683e6285f64", size = 261254 }, - { url = "https://files.pythonhosted.org/packages/8d/aa/0e2b27bd88b40a4fb8dc53dd74eecac70edaa4c1dd0707eb2164da3675b3/multidict-6.7.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:9600082733859f00d79dee64effc7aef1beb26adb297416a4ad2116fd61374bd", size = 257967 }, - { url = "https://files.pythonhosted.org/packages/d0/8e/0c67b7120d5d5f6d874ed85a085f9dc770a7f9d8813e80f44a9fec820bb7/multidict-6.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:94218fcec4d72bc61df51c198d098ce2b378e0ccbac41ddbed5ef44092913288", size = 250085 }, - { url = "https://files.pythonhosted.org/packages/ba/55/b73e1d624ea4b8fd4dd07a3bb70f6e4c7c6c5d9d640a41c6ffe5cdbd2a55/multidict-6.7.0-cp313-cp313-win32.whl", hash = "sha256:a37bd74c3fa9d00be2d7b8eca074dc56bd8077ddd2917a839bd989612671ed17", size = 41713 }, - { url = "https://files.pythonhosted.org/packages/32/31/75c59e7d3b4205075b4c183fa4ca398a2daf2303ddf616b04ae6ef55cffe/multidict-6.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:30d193c6cc6d559db42b6bcec8a5d395d34d60c9877a0b71ecd7c204fcf15390", size = 45915 }, - { url = "https://files.pythonhosted.org/packages/31/2a/8987831e811f1184c22bc2e45844934385363ee61c0a2dcfa8f71b87e608/multidict-6.7.0-cp313-cp313-win_arm64.whl", hash = "sha256:ea3334cabe4d41b7ccd01e4d349828678794edbc2d3ae97fc162a3312095092e", size = 43077 }, - { url = "https://files.pythonhosted.org/packages/e8/68/7b3a5170a382a340147337b300b9eb25a9ddb573bcdfff19c0fa3f31ffba/multidict-6.7.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:ad9ce259f50abd98a1ca0aa6e490b58c316a0fce0617f609723e40804add2c00", size = 83114 }, - { url = "https://files.pythonhosted.org/packages/55/5c/3fa2d07c84df4e302060f555bbf539310980362236ad49f50eeb0a1c1eb9/multidict-6.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07f5594ac6d084cbb5de2df218d78baf55ef150b91f0ff8a21cc7a2e3a5a58eb", size = 48442 }, - { url = "https://files.pythonhosted.org/packages/fc/56/67212d33239797f9bd91962bb899d72bb0f4c35a8652dcdb8ed049bef878/multidict-6.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0591b48acf279821a579282444814a2d8d0af624ae0bc600aa4d1b920b6e924b", size = 46885 }, - { url = "https://files.pythonhosted.org/packages/46/d1/908f896224290350721597a61a69cd19b89ad8ee0ae1f38b3f5cd12ea2ac/multidict-6.7.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:749a72584761531d2b9467cfbdfd29487ee21124c304c4b6cb760d8777b27f9c", size = 242588 }, - { url = "https://files.pythonhosted.org/packages/ab/67/8604288bbd68680eee0ab568fdcb56171d8b23a01bcd5cb0c8fedf6e5d99/multidict-6.7.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b4c3d199f953acd5b446bf7c0de1fe25d94e09e79086f8dc2f48a11a129cdf1", size = 249966 }, - { url = "https://files.pythonhosted.org/packages/20/33/9228d76339f1ba51e3efef7da3ebd91964d3006217aae13211653193c3ff/multidict-6.7.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9fb0211dfc3b51efea2f349ec92c114d7754dd62c01f81c3e32b765b70c45c9b", size = 228618 }, - { url = "https://files.pythonhosted.org/packages/f8/2d/25d9b566d10cab1c42b3b9e5b11ef79c9111eaf4463b8c257a3bd89e0ead/multidict-6.7.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a027ec240fe73a8d6281872690b988eed307cd7d91b23998ff35ff577ca688b5", size = 257539 }, - { url = "https://files.pythonhosted.org/packages/b6/b1/8d1a965e6637fc33de3c0d8f414485c2b7e4af00f42cab3d84e7b955c222/multidict-6.7.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1d964afecdf3a8288789df2f5751dc0a8261138c3768d9af117ed384e538fad", size = 256345 }, - { url = "https://files.pythonhosted.org/packages/ba/0c/06b5a8adbdeedada6f4fb8d8f193d44a347223b11939b42953eeb6530b6b/multidict-6.7.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:caf53b15b1b7df9fbd0709aa01409000a2b4dd03a5f6f5cc548183c7c8f8b63c", size = 247934 }, - { url = "https://files.pythonhosted.org/packages/8f/31/b2491b5fe167ca044c6eb4b8f2c9f3b8a00b24c432c365358eadac5d7625/multidict-6.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:654030da3197d927f05a536a66186070e98765aa5142794c9904555d3a9d8fb5", size = 245243 }, - { url = "https://files.pythonhosted.org/packages/61/1a/982913957cb90406c8c94f53001abd9eafc271cb3e70ff6371590bec478e/multidict-6.7.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:2090d3718829d1e484706a2f525e50c892237b2bf9b17a79b059cb98cddc2f10", size = 235878 }, - { url = "https://files.pythonhosted.org/packages/be/c0/21435d804c1a1cf7a2608593f4d19bca5bcbd7a81a70b253fdd1c12af9c0/multidict-6.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:2d2cfeec3f6f45651b3d408c4acec0ebf3daa9bc8a112a084206f5db5d05b754", size = 243452 }, - { url = "https://files.pythonhosted.org/packages/54/0a/4349d540d4a883863191be6eb9a928846d4ec0ea007d3dcd36323bb058ac/multidict-6.7.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:4ef089f985b8c194d341eb2c24ae6e7408c9a0e2e5658699c92f497437d88c3c", size = 252312 }, - { url = "https://files.pythonhosted.org/packages/26/64/d5416038dbda1488daf16b676e4dbfd9674dde10a0cc8f4fc2b502d8125d/multidict-6.7.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e93a0617cd16998784bf4414c7e40f17a35d2350e5c6f0bd900d3a8e02bd3762", size = 246935 }, - { url = "https://files.pythonhosted.org/packages/9f/8c/8290c50d14e49f35e0bd4abc25e1bc7711149ca9588ab7d04f886cdf03d9/multidict-6.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f0feece2ef8ebc42ed9e2e8c78fc4aa3cf455733b507c09ef7406364c94376c6", size = 243385 }, - { url = "https://files.pythonhosted.org/packages/ef/a0/f83ae75e42d694b3fbad3e047670e511c138be747bc713cf1b10d5096416/multidict-6.7.0-cp313-cp313t-win32.whl", hash = "sha256:19a1d55338ec1be74ef62440ca9e04a2f001a04d0cc49a4983dc320ff0f3212d", size = 47777 }, - { url = "https://files.pythonhosted.org/packages/dc/80/9b174a92814a3830b7357307a792300f42c9e94664b01dee8e457551fa66/multidict-6.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3da4fb467498df97e986af166b12d01f05d2e04f978a9c1c680ea1988e0bc4b6", size = 53104 }, - { url = "https://files.pythonhosted.org/packages/cc/28/04baeaf0428d95bb7a7bea0e691ba2f31394338ba424fb0679a9ed0f4c09/multidict-6.7.0-cp313-cp313t-win_arm64.whl", hash = "sha256:b4121773c49a0776461f4a904cdf6264c88e42218aaa8407e803ca8025872792", size = 45503 }, - { url = "https://files.pythonhosted.org/packages/e2/b1/3da6934455dd4b261d4c72f897e3a5728eba81db59959f3a639245891baa/multidict-6.7.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3bab1e4aff7adaa34410f93b1f8e57c4b36b9af0426a76003f441ee1d3c7e842", size = 75128 }, - { url = "https://files.pythonhosted.org/packages/14/2c/f069cab5b51d175a1a2cb4ccdf7a2c2dabd58aa5bd933fa036a8d15e2404/multidict-6.7.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b8512bac933afc3e45fb2b18da8e59b78d4f408399a960339598374d4ae3b56b", size = 44410 }, - { url = "https://files.pythonhosted.org/packages/42/e2/64bb41266427af6642b6b128e8774ed84c11b80a90702c13ac0a86bb10cc/multidict-6.7.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:79dcf9e477bc65414ebfea98ffd013cb39552b5ecd62908752e0e413d6d06e38", size = 43205 }, - { url = "https://files.pythonhosted.org/packages/02/68/6b086fef8a3f1a8541b9236c594f0c9245617c29841f2e0395d979485cde/multidict-6.7.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:31bae522710064b5cbeddaf2e9f32b1abab70ac6ac91d42572502299e9953128", size = 245084 }, - { url = "https://files.pythonhosted.org/packages/15/ee/f524093232007cd7a75c1d132df70f235cfd590a7c9eaccd7ff422ef4ae8/multidict-6.7.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a0df7ff02397bb63e2fd22af2c87dfa39e8c7f12947bc524dbdc528282c7e34", size = 252667 }, - { url = "https://files.pythonhosted.org/packages/02/a5/eeb3f43ab45878f1895118c3ef157a480db58ede3f248e29b5354139c2c9/multidict-6.7.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7a0222514e8e4c514660e182d5156a415c13ef0aabbd71682fc714e327b95e99", size = 233590 }, - { url = "https://files.pythonhosted.org/packages/6a/1e/76d02f8270b97269d7e3dbd45644b1785bda457b474315f8cf999525a193/multidict-6.7.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2397ab4daaf2698eb51a76721e98db21ce4f52339e535725de03ea962b5a3202", size = 264112 }, - { url = "https://files.pythonhosted.org/packages/76/0b/c28a70ecb58963847c2a8efe334904cd254812b10e535aefb3bcce513918/multidict-6.7.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8891681594162635948a636c9fe0ff21746aeb3dd5463f6e25d9bea3a8a39ca1", size = 261194 }, - { url = "https://files.pythonhosted.org/packages/b4/63/2ab26e4209773223159b83aa32721b4021ffb08102f8ac7d689c943fded1/multidict-6.7.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18706cc31dbf402a7945916dd5cddf160251b6dab8a2c5f3d6d5a55949f676b3", size = 248510 }, - { url = "https://files.pythonhosted.org/packages/93/cd/06c1fa8282af1d1c46fd55c10a7930af652afdce43999501d4d68664170c/multidict-6.7.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f844a1bbf1d207dd311a56f383f7eda2d0e134921d45751842d8235e7778965d", size = 248395 }, - { url = "https://files.pythonhosted.org/packages/99/ac/82cb419dd6b04ccf9e7e61befc00c77614fc8134362488b553402ecd55ce/multidict-6.7.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:d4393e3581e84e5645506923816b9cc81f5609a778c7e7534054091acc64d1c6", size = 239520 }, - { url = "https://files.pythonhosted.org/packages/fa/f3/a0f9bf09493421bd8716a362e0cd1d244f5a6550f5beffdd6b47e885b331/multidict-6.7.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:fbd18dc82d7bf274b37aa48d664534330af744e03bccf696d6f4c6042e7d19e7", size = 245479 }, - { url = "https://files.pythonhosted.org/packages/8d/01/476d38fc73a212843f43c852b0eee266b6971f0e28329c2184a8df90c376/multidict-6.7.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:b6234e14f9314731ec45c42fc4554b88133ad53a09092cc48a88e771c125dadb", size = 258903 }, - { url = "https://files.pythonhosted.org/packages/49/6d/23faeb0868adba613b817d0e69c5f15531b24d462af8012c4f6de4fa8dc3/multidict-6.7.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:08d4379f9744d8f78d98c8673c06e202ffa88296f009c71bbafe8a6bf847d01f", size = 252333 }, - { url = "https://files.pythonhosted.org/packages/1e/cc/48d02ac22b30fa247f7dad82866e4b1015431092f4ba6ebc7e77596e0b18/multidict-6.7.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9fe04da3f79387f450fd0061d4dd2e45a72749d31bf634aecc9e27f24fdc4b3f", size = 243411 }, - { url = "https://files.pythonhosted.org/packages/4a/03/29a8bf5a18abf1fe34535c88adbdfa88c9fb869b5a3b120692c64abe8284/multidict-6.7.0-cp314-cp314-win32.whl", hash = "sha256:fbafe31d191dfa7c4c51f7a6149c9fb7e914dcf9ffead27dcfd9f1ae382b3885", size = 40940 }, - { url = "https://files.pythonhosted.org/packages/82/16/7ed27b680791b939de138f906d5cf2b4657b0d45ca6f5dd6236fdddafb1a/multidict-6.7.0-cp314-cp314-win_amd64.whl", hash = "sha256:2f67396ec0310764b9222a1728ced1ab638f61aadc6226f17a71dd9324f9a99c", size = 45087 }, - { url = "https://files.pythonhosted.org/packages/cd/3c/e3e62eb35a1950292fe39315d3c89941e30a9d07d5d2df42965ab041da43/multidict-6.7.0-cp314-cp314-win_arm64.whl", hash = "sha256:ba672b26069957ee369cfa7fc180dde1fc6f176eaf1e6beaf61fbebbd3d9c000", size = 42368 }, - { url = "https://files.pythonhosted.org/packages/8b/40/cd499bd0dbc5f1136726db3153042a735fffd0d77268e2ee20d5f33c010f/multidict-6.7.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:c1dcc7524066fa918c6a27d61444d4ee7900ec635779058571f70d042d86ed63", size = 82326 }, - { url = "https://files.pythonhosted.org/packages/13/8a/18e031eca251c8df76daf0288e6790561806e439f5ce99a170b4af30676b/multidict-6.7.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:27e0b36c2d388dc7b6ced3406671b401e84ad7eb0656b8f3a2f46ed0ce483718", size = 48065 }, - { url = "https://files.pythonhosted.org/packages/40/71/5e6701277470a87d234e433fb0a3a7deaf3bcd92566e421e7ae9776319de/multidict-6.7.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2a7baa46a22e77f0988e3b23d4ede5513ebec1929e34ee9495be535662c0dfe2", size = 46475 }, - { url = "https://files.pythonhosted.org/packages/fe/6a/bab00cbab6d9cfb57afe1663318f72ec28289ea03fd4e8236bb78429893a/multidict-6.7.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7bf77f54997a9166a2f5675d1201520586439424c2511723a7312bdb4bcc034e", size = 239324 }, - { url = "https://files.pythonhosted.org/packages/2a/5f/8de95f629fc22a7769ade8b41028e3e5a822c1f8904f618d175945a81ad3/multidict-6.7.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e011555abada53f1578d63389610ac8a5400fc70ce71156b0aa30d326f1a5064", size = 246877 }, - { url = "https://files.pythonhosted.org/packages/23/b4/38881a960458f25b89e9f4a4fdcb02ac101cfa710190db6e5528841e67de/multidict-6.7.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:28b37063541b897fd6a318007373930a75ca6d6ac7c940dbe14731ffdd8d498e", size = 225824 }, - { url = "https://files.pythonhosted.org/packages/1e/39/6566210c83f8a261575f18e7144736059f0c460b362e96e9cf797a24b8e7/multidict-6.7.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:05047ada7a2fde2631a0ed706f1fd68b169a681dfe5e4cf0f8e4cb6618bbc2cd", size = 253558 }, - { url = "https://files.pythonhosted.org/packages/00/a3/67f18315100f64c269f46e6c0319fa87ba68f0f64f2b8e7fd7c72b913a0b/multidict-6.7.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:716133f7d1d946a4e1b91b1756b23c088881e70ff180c24e864c26192ad7534a", size = 252339 }, - { url = "https://files.pythonhosted.org/packages/c8/2a/1cb77266afee2458d82f50da41beba02159b1d6b1f7973afc9a1cad1499b/multidict-6.7.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d1bed1b467ef657f2a0ae62844a607909ef1c6889562de5e1d505f74457d0b96", size = 244895 }, - { url = "https://files.pythonhosted.org/packages/dd/72/09fa7dd487f119b2eb9524946ddd36e2067c08510576d43ff68469563b3b/multidict-6.7.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ca43bdfa5d37bd6aee89d85e1d0831fb86e25541be7e9d376ead1b28974f8e5e", size = 241862 }, - { url = "https://files.pythonhosted.org/packages/65/92/bc1f8bd0853d8669300f732c801974dfc3702c3eeadae2f60cef54dc69d7/multidict-6.7.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:44b546bd3eb645fd26fb949e43c02a25a2e632e2ca21a35e2e132c8105dc8599", size = 232376 }, - { url = "https://files.pythonhosted.org/packages/09/86/ac39399e5cb9d0c2ac8ef6e10a768e4d3bc933ac808d49c41f9dc23337eb/multidict-6.7.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:a6ef16328011d3f468e7ebc326f24c1445f001ca1dec335b2f8e66bed3006394", size = 240272 }, - { url = "https://files.pythonhosted.org/packages/3d/b6/fed5ac6b8563ec72df6cb1ea8dac6d17f0a4a1f65045f66b6d3bf1497c02/multidict-6.7.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:5aa873cbc8e593d361ae65c68f85faadd755c3295ea2c12040ee146802f23b38", size = 248774 }, - { url = "https://files.pythonhosted.org/packages/6b/8d/b954d8c0dc132b68f760aefd45870978deec6818897389dace00fcde32ff/multidict-6.7.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:3d7b6ccce016e29df4b7ca819659f516f0bc7a4b3efa3bb2012ba06431b044f9", size = 242731 }, - { url = "https://files.pythonhosted.org/packages/16/9d/a2dac7009125d3540c2f54e194829ea18ac53716c61b655d8ed300120b0f/multidict-6.7.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:171b73bd4ee683d307599b66793ac80981b06f069b62eea1c9e29c9241aa66b0", size = 240193 }, - { url = "https://files.pythonhosted.org/packages/39/ca/c05f144128ea232ae2178b008d5011d4e2cea86e4ee8c85c2631b1b94802/multidict-6.7.0-cp314-cp314t-win32.whl", hash = "sha256:b2d7f80c4e1fd010b07cb26820aae86b7e73b681ee4889684fb8d2d4537aab13", size = 48023 }, - { url = "https://files.pythonhosted.org/packages/ba/8f/0a60e501584145588be1af5cc829265701ba3c35a64aec8e07cbb71d39bb/multidict-6.7.0-cp314-cp314t-win_amd64.whl", hash = "sha256:09929cab6fcb68122776d575e03c6cc64ee0b8fca48d17e135474b042ce515cd", size = 53507 }, - { url = "https://files.pythonhosted.org/packages/7f/ae/3148b988a9c6239903e786eac19c889fab607c31d6efa7fb2147e5680f23/multidict-6.7.0-cp314-cp314t-win_arm64.whl", hash = "sha256:cc41db090ed742f32bd2d2c721861725e6109681eddf835d0a82bd3a5c382827", size = 44804 }, - { url = "https://files.pythonhosted.org/packages/b7/da/7d22601b625e241d4f23ef1ebff8acfc60da633c9e7e7922e24d10f592b3/multidict-6.7.0-py3-none-any.whl", hash = "sha256:394fc5c42a333c9ffc3e421a4c85e08580d990e08b99f6bf35b4132114c5dcb3", size = 12317 }, -] - -[[package]] -name = "multiprocess" -version = "0.70.16" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "dill" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/b5/ae/04f39c5d0d0def03247c2893d6f2b83c136bf3320a2154d7b8858f2ba72d/multiprocess-0.70.16.tar.gz", hash = "sha256:161af703d4652a0e1410be6abccecde4a7ddffd19341be0a7011b94aeb171ac1", size = 1772603 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bc/f7/7ec7fddc92e50714ea3745631f79bd9c96424cb2702632521028e57d3a36/multiprocess-0.70.16-py310-none-any.whl", hash = "sha256:c4a9944c67bd49f823687463660a2d6daae94c289adff97e0f9d696ba6371d02", size = 134824 }, - { url = "https://files.pythonhosted.org/packages/50/15/b56e50e8debaf439f44befec5b2af11db85f6e0f344c3113ae0be0593a91/multiprocess-0.70.16-py311-none-any.whl", hash = "sha256:af4cabb0dac72abfb1e794fa7855c325fd2b55a10a44628a3c1ad3311c04127a", size = 143519 }, - { url = "https://files.pythonhosted.org/packages/0a/7d/a988f258104dcd2ccf1ed40fdc97e26c4ac351eeaf81d76e266c52d84e2f/multiprocess-0.70.16-py312-none-any.whl", hash = "sha256:fc0544c531920dde3b00c29863377f87e1632601092ea2daca74e4beb40faa2e", size = 146741 }, - { url = "https://files.pythonhosted.org/packages/ea/89/38df130f2c799090c978b366cfdf5b96d08de5b29a4a293df7f7429fa50b/multiprocess-0.70.16-py38-none-any.whl", hash = "sha256:a71d82033454891091a226dfc319d0cfa8019a4e888ef9ca910372a446de4435", size = 132628 }, - { url = "https://files.pythonhosted.org/packages/da/d9/f7f9379981e39b8c2511c9e0326d212accacb82f12fbfdc1aa2ce2a7b2b6/multiprocess-0.70.16-py39-none-any.whl", hash = "sha256:a0bafd3ae1b732eac64be2e72038231c1ba97724b60b09400d68f229fcc2fbf3", size = 133351 }, -] - [[package]] name = "murmurhash" version = "1.0.13" @@ -1793,6 +1341,74 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/15/0e/331df43df633e6105ff9cf45e0ce57762bd126a45ac16b25a43f6738d8a2/openai-2.6.1-py3-none-any.whl", hash = "sha256:904e4b5254a8416746a2f05649594fa41b19d799843cd134dac86167e094edef", size = 1005551 }, ] +[[package]] +name = "orjson" +version = "3.11.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c6/fe/ed708782d6709cc60eb4c2d8a361a440661f74134675c72990f2c48c785f/orjson-3.11.4.tar.gz", hash = "sha256:39485f4ab4c9b30a3943cfe99e1a213c4776fb69e8abd68f66b83d5a0b0fdc6d", size = 5945188 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/63/1d/1ea6005fffb56715fd48f632611e163d1604e8316a5bad2288bee9a1c9eb/orjson-3.11.4-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5e59d23cd93ada23ec59a96f215139753fbfe3a4d989549bcb390f8c00370b39", size = 243498 }, + { url = "https://files.pythonhosted.org/packages/37/d7/ffed10c7da677f2a9da307d491b9eb1d0125b0307019c4ad3d665fd31f4f/orjson-3.11.4-cp311-cp311-macosx_15_0_arm64.whl", hash = "sha256:5c3aedecfc1beb988c27c79d52ebefab93b6c3921dbec361167e6559aba2d36d", size = 128961 }, + { url = "https://files.pythonhosted.org/packages/a2/96/3e4d10a18866d1368f73c8c44b7fe37cc8a15c32f2a7620be3877d4c55a3/orjson-3.11.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da9e5301f1c2caa2a9a4a303480d79c9ad73560b2e7761de742ab39fe59d9175", size = 130321 }, + { url = "https://files.pythonhosted.org/packages/eb/1f/465f66e93f434f968dd74d5b623eb62c657bdba2332f5a8be9f118bb74c7/orjson-3.11.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8873812c164a90a79f65368f8f96817e59e35d0cc02786a5356f0e2abed78040", size = 129207 }, + { url = "https://files.pythonhosted.org/packages/28/43/d1e94837543321c119dff277ae8e348562fe8c0fafbb648ef7cb0c67e521/orjson-3.11.4-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5d7feb0741ebb15204e748f26c9638e6665a5fa93c37a2c73d64f1669b0ddc63", size = 136323 }, + { url = "https://files.pythonhosted.org/packages/bf/04/93303776c8890e422a5847dd012b4853cdd88206b8bbd3edc292c90102d1/orjson-3.11.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:01ee5487fefee21e6910da4c2ee9eef005bee568a0879834df86f888d2ffbdd9", size = 137440 }, + { url = "https://files.pythonhosted.org/packages/1e/ef/75519d039e5ae6b0f34d0336854d55544ba903e21bf56c83adc51cd8bf82/orjson-3.11.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d40d46f348c0321df01507f92b95a377240c4ec31985225a6668f10e2676f9a", size = 136680 }, + { url = "https://files.pythonhosted.org/packages/b5/18/bf8581eaae0b941b44efe14fee7b7862c3382fbc9a0842132cfc7cf5ecf4/orjson-3.11.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95713e5fc8af84d8edc75b785d2386f653b63d62b16d681687746734b4dfc0be", size = 136160 }, + { url = "https://files.pythonhosted.org/packages/c4/35/a6d582766d351f87fc0a22ad740a641b0a8e6fc47515e8614d2e4790ae10/orjson-3.11.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ad73ede24f9083614d6c4ca9a85fe70e33be7bf047ec586ee2363bc7418fe4d7", size = 140318 }, + { url = "https://files.pythonhosted.org/packages/76/b3/5a4801803ab2e2e2d703bce1a56540d9f99a9143fbec7bf63d225044fef8/orjson-3.11.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:842289889de515421f3f224ef9c1f1efb199a32d76d8d2ca2706fa8afe749549", size = 406330 }, + { url = "https://files.pythonhosted.org/packages/80/55/a8f682f64833e3a649f620eafefee175cbfeb9854fc5b710b90c3bca45df/orjson-3.11.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:3b2427ed5791619851c52a1261b45c233930977e7de8cf36de05636c708fa905", size = 149580 }, + { url = "https://files.pythonhosted.org/packages/ad/e4/c132fa0c67afbb3eb88274fa98df9ac1f631a675e7877037c611805a4413/orjson-3.11.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3c36e524af1d29982e9b190573677ea02781456b2e537d5840e4538a5ec41907", size = 139846 }, + { url = "https://files.pythonhosted.org/packages/54/06/dc3491489efd651fef99c5908e13951abd1aead1257c67f16135f95ce209/orjson-3.11.4-cp311-cp311-win32.whl", hash = "sha256:87255b88756eab4a68ec61837ca754e5d10fa8bc47dc57f75cedfeaec358d54c", size = 135781 }, + { url = "https://files.pythonhosted.org/packages/79/b7/5e5e8d77bd4ea02a6ac54c42c818afb01dd31961be8a574eb79f1d2cfb1e/orjson-3.11.4-cp311-cp311-win_amd64.whl", hash = "sha256:e2d5d5d798aba9a0e1fede8d853fa899ce2cb930ec0857365f700dffc2c7af6a", size = 131391 }, + { url = "https://files.pythonhosted.org/packages/0f/dc/9484127cc1aa213be398ed735f5f270eedcb0c0977303a6f6ddc46b60204/orjson-3.11.4-cp311-cp311-win_arm64.whl", hash = "sha256:6bb6bb41b14c95d4f2702bce9975fda4516f1db48e500102fc4d8119032ff045", size = 126252 }, + { url = "https://files.pythonhosted.org/packages/63/51/6b556192a04595b93e277a9ff71cd0cc06c21a7df98bcce5963fa0f5e36f/orjson-3.11.4-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:d4371de39319d05d3f482f372720b841c841b52f5385bd99c61ed69d55d9ab50", size = 243571 }, + { url = "https://files.pythonhosted.org/packages/1c/2c/2602392ddf2601d538ff11848b98621cd465d1a1ceb9db9e8043181f2f7b/orjson-3.11.4-cp312-cp312-macosx_15_0_arm64.whl", hash = "sha256:e41fd3b3cac850eaae78232f37325ed7d7436e11c471246b87b2cd294ec94853", size = 128891 }, + { url = "https://files.pythonhosted.org/packages/4e/47/bf85dcf95f7a3a12bf223394a4f849430acd82633848d52def09fa3f46ad/orjson-3.11.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:600e0e9ca042878c7fdf189cf1b028fe2c1418cc9195f6cb9824eb6ed99cb938", size = 130137 }, + { url = "https://files.pythonhosted.org/packages/b4/4d/a0cb31007f3ab6f1fd2a1b17057c7c349bc2baf8921a85c0180cc7be8011/orjson-3.11.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7bbf9b333f1568ef5da42bc96e18bf30fd7f8d54e9ae066d711056add508e415", size = 129152 }, + { url = "https://files.pythonhosted.org/packages/f7/ef/2811def7ce3d8576b19e3929fff8f8f0d44bc5eb2e0fdecb2e6e6cc6c720/orjson-3.11.4-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4806363144bb6e7297b8e95870e78d30a649fdc4e23fc84daa80c8ebd366ce44", size = 136834 }, + { url = "https://files.pythonhosted.org/packages/00/d4/9aee9e54f1809cec8ed5abd9bc31e8a9631d19460e3b8470145d25140106/orjson-3.11.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad355e8308493f527d41154e9053b86a5be892b3b359a5c6d5d95cda23601cb2", size = 137519 }, + { url = "https://files.pythonhosted.org/packages/db/ea/67bfdb5465d5679e8ae8d68c11753aaf4f47e3e7264bad66dc2f2249e643/orjson-3.11.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c8a7517482667fb9f0ff1b2f16fe5829296ed7a655d04d68cd9711a4d8a4e708", size = 136749 }, + { url = "https://files.pythonhosted.org/packages/01/7e/62517dddcfce6d53a39543cd74d0dccfcbdf53967017c58af68822100272/orjson-3.11.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97eb5942c7395a171cbfecc4ef6701fc3c403e762194683772df4c54cfbb2210", size = 136325 }, + { url = "https://files.pythonhosted.org/packages/18/ae/40516739f99ab4c7ec3aaa5cc242d341fcb03a45d89edeeaabc5f69cb2cf/orjson-3.11.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:149d95d5e018bdd822e3f38c103b1a7c91f88d38a88aada5c4e9b3a73a244241", size = 140204 }, + { url = "https://files.pythonhosted.org/packages/82/18/ff5734365623a8916e3a4037fcef1cd1782bfc14cf0992afe7940c5320bf/orjson-3.11.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:624f3951181eb46fc47dea3d221554e98784c823e7069edb5dbd0dc826ac909b", size = 406242 }, + { url = "https://files.pythonhosted.org/packages/e1/43/96436041f0a0c8c8deca6a05ebeaf529bf1de04839f93ac5e7c479807aec/orjson-3.11.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:03bfa548cf35e3f8b3a96c4e8e41f753c686ff3d8e182ce275b1751deddab58c", size = 150013 }, + { url = "https://files.pythonhosted.org/packages/1b/48/78302d98423ed8780479a1e682b9aecb869e8404545d999d34fa486e573e/orjson-3.11.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:525021896afef44a68148f6ed8a8bf8375553d6066c7f48537657f64823565b9", size = 139951 }, + { url = "https://files.pythonhosted.org/packages/4a/7b/ad613fdcdaa812f075ec0875143c3d37f8654457d2af17703905425981bf/orjson-3.11.4-cp312-cp312-win32.whl", hash = "sha256:b58430396687ce0f7d9eeb3dd47761ca7d8fda8e9eb92b3077a7a353a75efefa", size = 136049 }, + { url = "https://files.pythonhosted.org/packages/b9/3c/9cf47c3ff5f39b8350fb21ba65d789b6a1129d4cbb3033ba36c8a9023520/orjson-3.11.4-cp312-cp312-win_amd64.whl", hash = "sha256:c6dbf422894e1e3c80a177133c0dda260f81428f9de16d61041949f6a2e5c140", size = 131461 }, + { url = "https://files.pythonhosted.org/packages/c6/3b/e2425f61e5825dc5b08c2a5a2b3af387eaaca22a12b9c8c01504f8614c36/orjson-3.11.4-cp312-cp312-win_arm64.whl", hash = "sha256:d38d2bc06d6415852224fcc9c0bfa834c25431e466dc319f0edd56cca81aa96e", size = 126167 }, + { url = "https://files.pythonhosted.org/packages/23/15/c52aa7112006b0f3d6180386c3a46ae057f932ab3425bc6f6ac50431cca1/orjson-3.11.4-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2d6737d0e616a6e053c8b4acc9eccea6b6cce078533666f32d140e4f85002534", size = 243525 }, + { url = "https://files.pythonhosted.org/packages/ec/38/05340734c33b933fd114f161f25a04e651b0c7c33ab95e9416ade5cb44b8/orjson-3.11.4-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:afb14052690aa328cc118a8e09f07c651d301a72e44920b887c519b313d892ff", size = 128871 }, + { url = "https://files.pythonhosted.org/packages/55/b9/ae8d34899ff0c012039b5a7cb96a389b2476e917733294e498586b45472d/orjson-3.11.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38aa9e65c591febb1b0aed8da4d469eba239d434c218562df179885c94e1a3ad", size = 130055 }, + { url = "https://files.pythonhosted.org/packages/33/aa/6346dd5073730451bee3681d901e3c337e7ec17342fb79659ec9794fc023/orjson-3.11.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f2cf4dfaf9163b0728d061bebc1e08631875c51cd30bf47cb9e3293bfbd7dcd5", size = 129061 }, + { url = "https://files.pythonhosted.org/packages/39/e4/8eea51598f66a6c853c380979912d17ec510e8e66b280d968602e680b942/orjson-3.11.4-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:89216ff3dfdde0e4070932e126320a1752c9d9a758d6a32ec54b3b9334991a6a", size = 136541 }, + { url = "https://files.pythonhosted.org/packages/9a/47/cb8c654fa9adcc60e99580e17c32b9e633290e6239a99efa6b885aba9dbc/orjson-3.11.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9daa26ca8e97fae0ce8aa5d80606ef8f7914e9b129b6b5df9104266f764ce436", size = 137535 }, + { url = "https://files.pythonhosted.org/packages/43/92/04b8cc5c2b729f3437ee013ce14a60ab3d3001465d95c184758f19362f23/orjson-3.11.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c8b2769dc31883c44a9cd126560327767f848eb95f99c36c9932f51090bfce9", size = 136703 }, + { url = "https://files.pythonhosted.org/packages/aa/fd/d0733fcb9086b8be4ebcfcda2d0312865d17d0d9884378b7cffb29d0763f/orjson-3.11.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1469d254b9884f984026bd9b0fa5bbab477a4bfe558bba6848086f6d43eb5e73", size = 136293 }, + { url = "https://files.pythonhosted.org/packages/c2/d7/3c5514e806837c210492d72ae30ccf050ce3f940f45bf085bab272699ef4/orjson-3.11.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:68e44722541983614e37117209a194e8c3ad07838ccb3127d96863c95ec7f1e0", size = 140131 }, + { url = "https://files.pythonhosted.org/packages/9c/dd/ba9d32a53207babf65bd510ac4d0faaa818bd0df9a9c6f472fe7c254f2e3/orjson-3.11.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:8e7805fda9672c12be2f22ae124dcd7b03928d6c197544fe12174b86553f3196", size = 406164 }, + { url = "https://files.pythonhosted.org/packages/8e/f9/f68ad68f4af7c7bde57cd514eaa2c785e500477a8bc8f834838eb696a685/orjson-3.11.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:04b69c14615fb4434ab867bf6f38b2d649f6f300af30a6705397e895f7aec67a", size = 149859 }, + { url = "https://files.pythonhosted.org/packages/b6/d2/7f847761d0c26818395b3d6b21fb6bc2305d94612a35b0a30eae65a22728/orjson-3.11.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:639c3735b8ae7f970066930e58cf0ed39a852d417c24acd4a25fc0b3da3c39a6", size = 139926 }, + { url = "https://files.pythonhosted.org/packages/9f/37/acd14b12dc62db9a0e1d12386271b8661faae270b22492580d5258808975/orjson-3.11.4-cp313-cp313-win32.whl", hash = "sha256:6c13879c0d2964335491463302a6ca5ad98105fc5db3565499dcb80b1b4bd839", size = 136007 }, + { url = "https://files.pythonhosted.org/packages/c0/a9/967be009ddf0a1fffd7a67de9c36656b28c763659ef91352acc02cbe364c/orjson-3.11.4-cp313-cp313-win_amd64.whl", hash = "sha256:09bf242a4af98732db9f9a1ec57ca2604848e16f132e3f72edfd3c5c96de009a", size = 131314 }, + { url = "https://files.pythonhosted.org/packages/cb/db/399abd6950fbd94ce125cb8cd1a968def95174792e127b0642781e040ed4/orjson-3.11.4-cp313-cp313-win_arm64.whl", hash = "sha256:a85f0adf63319d6c1ba06fb0dbf997fced64a01179cf17939a6caca662bf92de", size = 126152 }, + { url = "https://files.pythonhosted.org/packages/25/e3/54ff63c093cc1697e758e4fceb53164dd2661a7d1bcd522260ba09f54533/orjson-3.11.4-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:42d43a1f552be1a112af0b21c10a5f553983c2a0938d2bbb8ecd8bc9fb572803", size = 243501 }, + { url = "https://files.pythonhosted.org/packages/ac/7d/e2d1076ed2e8e0ae9badca65bf7ef22710f93887b29eaa37f09850604e09/orjson-3.11.4-cp314-cp314-macosx_15_0_arm64.whl", hash = "sha256:26a20f3fbc6c7ff2cb8e89c4c5897762c9d88cf37330c6a117312365d6781d54", size = 128862 }, + { url = "https://files.pythonhosted.org/packages/9f/37/ca2eb40b90621faddfa9517dfe96e25f5ae4d8057a7c0cdd613c17e07b2c/orjson-3.11.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e3f20be9048941c7ffa8fc523ccbd17f82e24df1549d1d1fe9317712d19938e", size = 130047 }, + { url = "https://files.pythonhosted.org/packages/c7/62/1021ed35a1f2bad9040f05fa4cc4f9893410df0ba3eaa323ccf899b1c90a/orjson-3.11.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aac364c758dc87a52e68e349924d7e4ded348dedff553889e4d9f22f74785316", size = 129073 }, + { url = "https://files.pythonhosted.org/packages/e8/3f/f84d966ec2a6fd5f73b1a707e7cd876813422ae4bf9f0145c55c9c6a0f57/orjson-3.11.4-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d5c54a6d76e3d741dcc3f2707f8eeb9ba2a791d3adbf18f900219b62942803b1", size = 136597 }, + { url = "https://files.pythonhosted.org/packages/32/78/4fa0aeca65ee82bbabb49e055bd03fa4edea33f7c080c5c7b9601661ef72/orjson-3.11.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f28485bdca8617b79d44627f5fb04336897041dfd9fa66d383a49d09d86798bc", size = 137515 }, + { url = "https://files.pythonhosted.org/packages/c1/9d/0c102e26e7fde40c4c98470796d050a2ec1953897e2c8ab0cb95b0759fa2/orjson-3.11.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bfc2a484cad3585e4ba61985a6062a4c2ed5c7925db6d39f1fa267c9d166487f", size = 136703 }, + { url = "https://files.pythonhosted.org/packages/df/ac/2de7188705b4cdfaf0b6c97d2f7849c17d2003232f6e70df98602173f788/orjson-3.11.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e34dbd508cb91c54f9c9788923daca129fe5b55c5b4eebe713bf5ed3791280cf", size = 136311 }, + { url = "https://files.pythonhosted.org/packages/e0/52/847fcd1a98407154e944feeb12e3b4d487a0e264c40191fb44d1269cbaa1/orjson-3.11.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b13c478fa413d4b4ee606ec8e11c3b2e52683a640b006bb586b3041c2ca5f606", size = 140127 }, + { url = "https://files.pythonhosted.org/packages/c1/ae/21d208f58bdb847dd4d0d9407e2929862561841baa22bdab7aea10ca088e/orjson-3.11.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:724ca721ecc8a831b319dcd72cfa370cc380db0bf94537f08f7edd0a7d4e1780", size = 406201 }, + { url = "https://files.pythonhosted.org/packages/8d/55/0789d6de386c8366059db098a628e2ad8798069e94409b0d8935934cbcb9/orjson-3.11.4-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:977c393f2e44845ce1b540e19a786e9643221b3323dae190668a98672d43fb23", size = 149872 }, + { url = "https://files.pythonhosted.org/packages/cc/1d/7ff81ea23310e086c17b41d78a72270d9de04481e6113dbe2ac19118f7fb/orjson-3.11.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1e539e382cf46edec157ad66b0b0872a90d829a6b71f17cb633d6c160a223155", size = 139931 }, + { url = "https://files.pythonhosted.org/packages/77/92/25b886252c50ed64be68c937b562b2f2333b45afe72d53d719e46a565a50/orjson-3.11.4-cp314-cp314-win32.whl", hash = "sha256:d63076d625babab9db5e7836118bdfa086e60f37d8a174194ae720161eb12394", size = 136065 }, + { url = "https://files.pythonhosted.org/packages/63/b8/718eecf0bb7e9d64e4956afaafd23db9f04c776d445f59fe94f54bdae8f0/orjson-3.11.4-cp314-cp314-win_amd64.whl", hash = "sha256:0a54d6635fa3aaa438ae32e8570b9f0de36f3f6562c308d2a2a452e8b0592db1", size = 131310 }, + { url = "https://files.pythonhosted.org/packages/1a/bf/def5e25d4d8bfce296a9a7c8248109bf58622c21618b590678f945a2c59c/orjson-3.11.4-cp314-cp314-win_arm64.whl", hash = "sha256:78b999999039db3cf58f6d230f524f04f75f129ba3d1ca2ed121f8657e575d3d", size = 126151 }, +] + [[package]] name = "packaging" version = "25.0" @@ -1802,81 +1418,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469 }, ] -[[package]] -name = "pandas" -version = "2.3.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "numpy" }, - { name = "python-dateutil" }, - { name = "pytz" }, - { name = "tzdata" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/fa/7ac648108144a095b4fb6aa3de1954689f7af60a14cf25583f4960ecb878/pandas-2.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:602b8615ebcc4a0c1751e71840428ddebeb142ec02c786e8ad6b1ce3c8dec523", size = 11578790 }, - { url = "https://files.pythonhosted.org/packages/9b/35/74442388c6cf008882d4d4bdfc4109be87e9b8b7ccd097ad1e7f006e2e95/pandas-2.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8fe25fc7b623b0ef6b5009149627e34d2a4657e880948ec3c840e9402e5c1b45", size = 10833831 }, - { url = "https://files.pythonhosted.org/packages/fe/e4/de154cbfeee13383ad58d23017da99390b91d73f8c11856f2095e813201b/pandas-2.3.3-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b468d3dad6ff947df92dcb32ede5b7bd41a9b3cceef0a30ed925f6d01fb8fa66", size = 12199267 }, - { url = "https://files.pythonhosted.org/packages/bf/c9/63f8d545568d9ab91476b1818b4741f521646cbdd151c6efebf40d6de6f7/pandas-2.3.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b98560e98cb334799c0b07ca7967ac361a47326e9b4e5a7dfb5ab2b1c9d35a1b", size = 12789281 }, - { url = "https://files.pythonhosted.org/packages/f2/00/a5ac8c7a0e67fd1a6059e40aa08fa1c52cc00709077d2300e210c3ce0322/pandas-2.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37b5848ba49824e5c30bedb9c830ab9b7751fd049bc7914533e01c65f79791", size = 13240453 }, - { url = "https://files.pythonhosted.org/packages/27/4d/5c23a5bc7bd209231618dd9e606ce076272c9bc4f12023a70e03a86b4067/pandas-2.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:db4301b2d1f926ae677a751eb2bd0e8c5f5319c9cb3f88b0becbbb0b07b34151", size = 13890361 }, - { url = "https://files.pythonhosted.org/packages/8e/59/712db1d7040520de7a4965df15b774348980e6df45c129b8c64d0dbe74ef/pandas-2.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:f086f6fe114e19d92014a1966f43a3e62285109afe874f067f5abbdcbb10e59c", size = 11348702 }, - { url = "https://files.pythonhosted.org/packages/9c/fb/231d89e8637c808b997d172b18e9d4a4bc7bf31296196c260526055d1ea0/pandas-2.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d21f6d74eb1725c2efaa71a2bfc661a0689579b58e9c0ca58a739ff0b002b53", size = 11597846 }, - { url = "https://files.pythonhosted.org/packages/5c/bd/bf8064d9cfa214294356c2d6702b716d3cf3bb24be59287a6a21e24cae6b/pandas-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3fd2f887589c7aa868e02632612ba39acb0b8948faf5cc58f0850e165bd46f35", size = 10729618 }, - { url = "https://files.pythonhosted.org/packages/57/56/cf2dbe1a3f5271370669475ead12ce77c61726ffd19a35546e31aa8edf4e/pandas-2.3.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecaf1e12bdc03c86ad4a7ea848d66c685cb6851d807a26aa245ca3d2017a1908", size = 11737212 }, - { url = "https://files.pythonhosted.org/packages/e5/63/cd7d615331b328e287d8233ba9fdf191a9c2d11b6af0c7a59cfcec23de68/pandas-2.3.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b3d11d2fda7eb164ef27ffc14b4fcab16a80e1ce67e9f57e19ec0afaf715ba89", size = 12362693 }, - { url = "https://files.pythonhosted.org/packages/a6/de/8b1895b107277d52f2b42d3a6806e69cfef0d5cf1d0ba343470b9d8e0a04/pandas-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a68e15f780eddf2b07d242e17a04aa187a7ee12b40b930bfdd78070556550e98", size = 12771002 }, - { url = "https://files.pythonhosted.org/packages/87/21/84072af3187a677c5893b170ba2c8fbe450a6ff911234916da889b698220/pandas-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:371a4ab48e950033bcf52b6527eccb564f52dc826c02afd9a1bc0ab731bba084", size = 13450971 }, - { url = "https://files.pythonhosted.org/packages/86/41/585a168330ff063014880a80d744219dbf1dd7a1c706e75ab3425a987384/pandas-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:a16dcec078a01eeef8ee61bf64074b4e524a2a3f4b3be9326420cabe59c4778b", size = 10992722 }, - { url = "https://files.pythonhosted.org/packages/cd/4b/18b035ee18f97c1040d94debd8f2e737000ad70ccc8f5513f4eefad75f4b/pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713", size = 11544671 }, - { url = "https://files.pythonhosted.org/packages/31/94/72fac03573102779920099bcac1c3b05975c2cb5f01eac609faf34bed1ca/pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8", size = 10680807 }, - { url = "https://files.pythonhosted.org/packages/16/87/9472cf4a487d848476865321de18cc8c920b8cab98453ab79dbbc98db63a/pandas-2.3.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d", size = 11709872 }, - { url = "https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac", size = 12306371 }, - { url = "https://files.pythonhosted.org/packages/33/81/a3afc88fca4aa925804a27d2676d22dcd2031c2ebe08aabd0ae55b9ff282/pandas-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c", size = 12765333 }, - { url = "https://files.pythonhosted.org/packages/8d/0f/b4d4ae743a83742f1153464cf1a8ecfafc3ac59722a0b5c8602310cb7158/pandas-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493", size = 13418120 }, - { url = "https://files.pythonhosted.org/packages/4f/c7/e54682c96a895d0c808453269e0b5928a07a127a15704fedb643e9b0a4c8/pandas-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee", size = 10993991 }, - { url = "https://files.pythonhosted.org/packages/f9/ca/3f8d4f49740799189e1395812f3bf23b5e8fc7c190827d55a610da72ce55/pandas-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5", size = 12048227 }, - { url = "https://files.pythonhosted.org/packages/0e/5a/f43efec3e8c0cc92c4663ccad372dbdff72b60bdb56b2749f04aa1d07d7e/pandas-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21", size = 11411056 }, - { url = "https://files.pythonhosted.org/packages/46/b1/85331edfc591208c9d1a63a06baa67b21d332e63b7a591a5ba42a10bb507/pandas-2.3.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78", size = 11645189 }, - { url = "https://files.pythonhosted.org/packages/44/23/78d645adc35d94d1ac4f2a3c4112ab6f5b8999f4898b8cdf01252f8df4a9/pandas-2.3.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110", size = 12121912 }, - { url = "https://files.pythonhosted.org/packages/53/da/d10013df5e6aaef6b425aa0c32e1fc1f3e431e4bcabd420517dceadce354/pandas-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86", size = 12712160 }, - { url = "https://files.pythonhosted.org/packages/bd/17/e756653095a083d8a37cbd816cb87148debcfcd920129b25f99dd8d04271/pandas-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc", size = 13199233 }, - { url = "https://files.pythonhosted.org/packages/04/fd/74903979833db8390b73b3a8a7d30d146d710bd32703724dd9083950386f/pandas-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0", size = 11540635 }, - { url = "https://files.pythonhosted.org/packages/21/00/266d6b357ad5e6d3ad55093a7e8efc7dd245f5a842b584db9f30b0f0a287/pandas-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593", size = 10759079 }, - { url = "https://files.pythonhosted.org/packages/ca/05/d01ef80a7a3a12b2f8bbf16daba1e17c98a2f039cbc8e2f77a2c5a63d382/pandas-2.3.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c", size = 11814049 }, - { url = "https://files.pythonhosted.org/packages/15/b2/0e62f78c0c5ba7e3d2c5945a82456f4fac76c480940f805e0b97fcbc2f65/pandas-2.3.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b", size = 12332638 }, - { url = "https://files.pythonhosted.org/packages/c5/33/dd70400631b62b9b29c3c93d2feee1d0964dc2bae2e5ad7a6c73a7f25325/pandas-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6", size = 12886834 }, - { url = "https://files.pythonhosted.org/packages/d3/18/b5d48f55821228d0d2692b34fd5034bb185e854bdb592e9c640f6290e012/pandas-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3", size = 13409925 }, - { url = "https://files.pythonhosted.org/packages/a6/3d/124ac75fcd0ecc09b8fdccb0246ef65e35b012030defb0e0eba2cbbbe948/pandas-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5", size = 11109071 }, - { url = "https://files.pythonhosted.org/packages/89/9c/0e21c895c38a157e0faa1fb64587a9226d6dd46452cac4532d80c3c4a244/pandas-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec", size = 12048504 }, - { url = "https://files.pythonhosted.org/packages/d7/82/b69a1c95df796858777b68fbe6a81d37443a33319761d7c652ce77797475/pandas-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7", size = 11410702 }, - { url = "https://files.pythonhosted.org/packages/f9/88/702bde3ba0a94b8c73a0181e05144b10f13f29ebfc2150c3a79062a8195d/pandas-2.3.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450", size = 11634535 }, - { url = "https://files.pythonhosted.org/packages/a4/1e/1bac1a839d12e6a82ec6cb40cda2edde64a2013a66963293696bbf31fbbb/pandas-2.3.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5", size = 12121582 }, - { url = "https://files.pythonhosted.org/packages/44/91/483de934193e12a3b1d6ae7c8645d083ff88dec75f46e827562f1e4b4da6/pandas-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788", size = 12699963 }, - { url = "https://files.pythonhosted.org/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175 }, -] - -[[package]] -name = "parso" -version = "0.8.5" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d4/de/53e0bcf53d13e005bd8c92e7855142494f41171b34c2536b86187474184d/parso-0.8.5.tar.gz", hash = "sha256:034d7354a9a018bdce352f48b2a8a450f05e9d6ee85db84764e9b6bd96dafe5a", size = 401205 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/16/32/f8e3c85d1d5250232a5d3477a2a28cc291968ff175caeadaf3cc19ce0e4a/parso-0.8.5-py2.py3-none-any.whl", hash = "sha256:646204b5ee239c396d040b90f9e272e9a8017c630092bf59980beb62fd033887", size = 106668 }, -] - -[[package]] -name = "pexpect" -version = "4.9.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "ptyprocess" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772 }, -] - [[package]] name = "pgvector" version = "0.4.1" @@ -2018,117 +1559,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fa/8c/d3e30f80b2ef21f267f09f0b7d18995adccc928ede5b73ea3fe54e1303f4/preshed-3.0.10-cp313-cp313-win_amd64.whl", hash = "sha256:97e0e2edfd25a7dfba799b49b3c5cc248ad0318a76edd9d5fd2c82aa3d5c64ed", size = 115769 }, ] -[[package]] -name = "prompt-toolkit" -version = "3.0.52" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "wcwidth" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a1/96/06e01a7b38dce6fe1db213e061a4602dd6032a8a97ef6c1a862537732421/prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855", size = 434198 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955", size = 391431 }, -] - -[[package]] -name = "propcache" -version = "0.4.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9e/da/e9fc233cf63743258bff22b3dfa7ea5baef7b5bc324af47a0ad89b8ffc6f/propcache-0.4.1.tar.gz", hash = "sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d", size = 46442 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8c/d4/4e2c9aaf7ac2242b9358f98dccd8f90f2605402f5afeff6c578682c2c491/propcache-0.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:60a8fda9644b7dfd5dece8c61d8a85e271cb958075bfc4e01083c148b61a7caf", size = 80208 }, - { url = "https://files.pythonhosted.org/packages/c2/21/d7b68e911f9c8e18e4ae43bdbc1e1e9bbd971f8866eb81608947b6f585ff/propcache-0.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c30b53e7e6bda1d547cabb47c825f3843a0a1a42b0496087bb58d8fedf9f41b5", size = 45777 }, - { url = "https://files.pythonhosted.org/packages/d3/1d/11605e99ac8ea9435651ee71ab4cb4bf03f0949586246476a25aadfec54a/propcache-0.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e", size = 47647 }, - { url = "https://files.pythonhosted.org/packages/58/1a/3c62c127a8466c9c843bccb503d40a273e5cc69838805f322e2826509e0d/propcache-0.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3d902a36df4e5989763425a8ab9e98cd8ad5c52c823b34ee7ef307fd50582566", size = 214929 }, - { url = "https://files.pythonhosted.org/packages/56/b9/8fa98f850960b367c4b8fe0592e7fc341daa7a9462e925228f10a60cf74f/propcache-0.4.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a9695397f85973bb40427dedddf70d8dc4a44b22f1650dd4af9eedf443d45165", size = 221778 }, - { url = "https://files.pythonhosted.org/packages/46/a6/0ab4f660eb59649d14b3d3d65c439421cf2f87fe5dd68591cbe3c1e78a89/propcache-0.4.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2bb07ffd7eaad486576430c89f9b215f9e4be68c4866a96e97db9e97fead85dc", size = 228144 }, - { url = "https://files.pythonhosted.org/packages/52/6a/57f43e054fb3d3a56ac9fc532bc684fc6169a26c75c353e65425b3e56eef/propcache-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48", size = 210030 }, - { url = "https://files.pythonhosted.org/packages/40/e2/27e6feebb5f6b8408fa29f5efbb765cd54c153ac77314d27e457a3e993b7/propcache-0.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fc38cba02d1acba4e2869eef1a57a43dfbd3d49a59bf90dda7444ec2be6a5570", size = 208252 }, - { url = "https://files.pythonhosted.org/packages/9e/f8/91c27b22ccda1dbc7967f921c42825564fa5336a01ecd72eb78a9f4f53c2/propcache-0.4.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:67fad6162281e80e882fb3ec355398cf72864a54069d060321f6cd0ade95fe85", size = 202064 }, - { url = "https://files.pythonhosted.org/packages/f2/26/7f00bd6bd1adba5aafe5f4a66390f243acab58eab24ff1a08bebb2ef9d40/propcache-0.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f10207adf04d08bec185bae14d9606a1444715bc99180f9331c9c02093e1959e", size = 212429 }, - { url = "https://files.pythonhosted.org/packages/84/89/fd108ba7815c1117ddca79c228f3f8a15fc82a73bca8b142eb5de13b2785/propcache-0.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e9b0d8d0845bbc4cfcdcbcdbf5086886bc8157aa963c31c777ceff7846c77757", size = 216727 }, - { url = "https://files.pythonhosted.org/packages/79/37/3ec3f7e3173e73f1d600495d8b545b53802cbf35506e5732dd8578db3724/propcache-0.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:981333cb2f4c1896a12f4ab92a9cc8f09ea664e9b7dbdc4eff74627af3a11c0f", size = 205097 }, - { url = "https://files.pythonhosted.org/packages/61/b0/b2631c19793f869d35f47d5a3a56fb19e9160d3c119f15ac7344fc3ccae7/propcache-0.4.1-cp311-cp311-win32.whl", hash = "sha256:f1d2f90aeec838a52f1c1a32fe9a619fefd5e411721a9117fbf82aea638fe8a1", size = 38084 }, - { url = "https://files.pythonhosted.org/packages/f4/78/6cce448e2098e9f3bfc91bb877f06aa24b6ccace872e39c53b2f707c4648/propcache-0.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6", size = 41637 }, - { url = "https://files.pythonhosted.org/packages/9c/e9/754f180cccd7f51a39913782c74717c581b9cc8177ad0e949f4d51812383/propcache-0.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:e53f3a38d3510c11953f3e6a33f205c6d1b001129f972805ca9b42fc308bc239", size = 38064 }, - { url = "https://files.pythonhosted.org/packages/a2/0f/f17b1b2b221d5ca28b4b876e8bb046ac40466513960646bda8e1853cdfa2/propcache-0.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2", size = 80061 }, - { url = "https://files.pythonhosted.org/packages/76/47/8ccf75935f51448ba9a16a71b783eb7ef6b9ee60f5d14c7f8a8a79fbeed7/propcache-0.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403", size = 46037 }, - { url = "https://files.pythonhosted.org/packages/0a/b6/5c9a0e42df4d00bfb4a3cbbe5cf9f54260300c88a0e9af1f47ca5ce17ac0/propcache-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207", size = 47324 }, - { url = "https://files.pythonhosted.org/packages/9e/d3/6c7ee328b39a81ee877c962469f1e795f9db87f925251efeb0545e0020d0/propcache-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72", size = 225505 }, - { url = "https://files.pythonhosted.org/packages/01/5d/1c53f4563490b1d06a684742cc6076ef944bc6457df6051b7d1a877c057b/propcache-0.4.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367", size = 230242 }, - { url = "https://files.pythonhosted.org/packages/20/e1/ce4620633b0e2422207c3cb774a0ee61cac13abc6217763a7b9e2e3f4a12/propcache-0.4.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4", size = 238474 }, - { url = "https://files.pythonhosted.org/packages/46/4b/3aae6835b8e5f44ea6a68348ad90f78134047b503765087be2f9912140ea/propcache-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf", size = 221575 }, - { url = "https://files.pythonhosted.org/packages/6e/a5/8a5e8678bcc9d3a1a15b9a29165640d64762d424a16af543f00629c87338/propcache-0.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3", size = 216736 }, - { url = "https://files.pythonhosted.org/packages/f1/63/b7b215eddeac83ca1c6b934f89d09a625aa9ee4ba158338854c87210cc36/propcache-0.4.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778", size = 213019 }, - { url = "https://files.pythonhosted.org/packages/57/74/f580099a58c8af587cac7ba19ee7cb418506342fbbe2d4a4401661cca886/propcache-0.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6", size = 220376 }, - { url = "https://files.pythonhosted.org/packages/c4/ee/542f1313aff7eaf19c2bb758c5d0560d2683dac001a1c96d0774af799843/propcache-0.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9", size = 226988 }, - { url = "https://files.pythonhosted.org/packages/8f/18/9c6b015dd9c6930f6ce2229e1f02fb35298b847f2087ea2b436a5bfa7287/propcache-0.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75", size = 215615 }, - { url = "https://files.pythonhosted.org/packages/80/9e/e7b85720b98c45a45e1fca6a177024934dc9bc5f4d5dd04207f216fc33ed/propcache-0.4.1-cp312-cp312-win32.whl", hash = "sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8", size = 38066 }, - { url = "https://files.pythonhosted.org/packages/54/09/d19cff2a5aaac632ec8fc03737b223597b1e347416934c1b3a7df079784c/propcache-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db", size = 41655 }, - { url = "https://files.pythonhosted.org/packages/68/ab/6b5c191bb5de08036a8c697b265d4ca76148efb10fa162f14af14fb5f076/propcache-0.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1", size = 37789 }, - { url = "https://files.pythonhosted.org/packages/bf/df/6d9c1b6ac12b003837dde8a10231a7344512186e87b36e855bef32241942/propcache-0.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf", size = 77750 }, - { url = "https://files.pythonhosted.org/packages/8b/e8/677a0025e8a2acf07d3418a2e7ba529c9c33caf09d3c1f25513023c1db56/propcache-0.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311", size = 44780 }, - { url = "https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74", size = 46308 }, - { url = "https://files.pythonhosted.org/packages/2d/48/c5ac64dee5262044348d1d78a5f85dd1a57464a60d30daee946699963eb3/propcache-0.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe", size = 208182 }, - { url = "https://files.pythonhosted.org/packages/c6/0c/cd762dd011a9287389a6a3eb43aa30207bde253610cca06824aeabfe9653/propcache-0.4.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af", size = 211215 }, - { url = "https://files.pythonhosted.org/packages/30/3e/49861e90233ba36890ae0ca4c660e95df565b2cd15d4a68556ab5865974e/propcache-0.4.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c", size = 218112 }, - { url = "https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f", size = 204442 }, - { url = "https://files.pythonhosted.org/packages/50/a6/4282772fd016a76d3e5c0df58380a5ea64900afd836cec2c2f662d1b9bb3/propcache-0.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1", size = 199398 }, - { url = "https://files.pythonhosted.org/packages/3e/ec/d8a7cd406ee1ddb705db2139f8a10a8a427100347bd698e7014351c7af09/propcache-0.4.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24", size = 196920 }, - { url = "https://files.pythonhosted.org/packages/f6/6c/f38ab64af3764f431e359f8baf9e0a21013e24329e8b85d2da32e8ed07ca/propcache-0.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa", size = 203748 }, - { url = "https://files.pythonhosted.org/packages/d6/e3/fa846bd70f6534d647886621388f0a265254d30e3ce47e5c8e6e27dbf153/propcache-0.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61", size = 205877 }, - { url = "https://files.pythonhosted.org/packages/e2/39/8163fc6f3133fea7b5f2827e8eba2029a0277ab2c5beee6c1db7b10fc23d/propcache-0.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66", size = 199437 }, - { url = "https://files.pythonhosted.org/packages/93/89/caa9089970ca49c7c01662bd0eeedfe85494e863e8043565aeb6472ce8fe/propcache-0.4.1-cp313-cp313-win32.whl", hash = "sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81", size = 37586 }, - { url = "https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e", size = 40790 }, - { url = "https://files.pythonhosted.org/packages/59/1b/e71ae98235f8e2ba5004d8cb19765a74877abf189bc53fc0c80d799e56c3/propcache-0.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1", size = 37158 }, - { url = "https://files.pythonhosted.org/packages/83/ce/a31bbdfc24ee0dcbba458c8175ed26089cf109a55bbe7b7640ed2470cfe9/propcache-0.4.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b", size = 81451 }, - { url = "https://files.pythonhosted.org/packages/25/9c/442a45a470a68456e710d96cacd3573ef26a1d0a60067e6a7d5e655621ed/propcache-0.4.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566", size = 46374 }, - { url = "https://files.pythonhosted.org/packages/f4/bf/b1d5e21dbc3b2e889ea4327044fb16312a736d97640fb8b6aa3f9c7b3b65/propcache-0.4.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835", size = 48396 }, - { url = "https://files.pythonhosted.org/packages/f4/04/5b4c54a103d480e978d3c8a76073502b18db0c4bc17ab91b3cb5092ad949/propcache-0.4.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e", size = 275950 }, - { url = "https://files.pythonhosted.org/packages/b4/c1/86f846827fb969c4b78b0af79bba1d1ea2156492e1b83dea8b8a6ae27395/propcache-0.4.1-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859", size = 273856 }, - { url = "https://files.pythonhosted.org/packages/36/1d/fc272a63c8d3bbad6878c336c7a7dea15e8f2d23a544bda43205dfa83ada/propcache-0.4.1-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b", size = 280420 }, - { url = "https://files.pythonhosted.org/packages/07/0c/01f2219d39f7e53d52e5173bcb09c976609ba30209912a0680adfb8c593a/propcache-0.4.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0", size = 263254 }, - { url = "https://files.pythonhosted.org/packages/2d/18/cd28081658ce597898f0c4d174d4d0f3c5b6d4dc27ffafeef835c95eb359/propcache-0.4.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af", size = 261205 }, - { url = "https://files.pythonhosted.org/packages/7a/71/1f9e22eb8b8316701c2a19fa1f388c8a3185082607da8e406a803c9b954e/propcache-0.4.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393", size = 247873 }, - { url = "https://files.pythonhosted.org/packages/4a/65/3d4b61f36af2b4eddba9def857959f1016a51066b4f1ce348e0cf7881f58/propcache-0.4.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874", size = 262739 }, - { url = "https://files.pythonhosted.org/packages/2a/42/26746ab087faa77c1c68079b228810436ccd9a5ce9ac85e2b7307195fd06/propcache-0.4.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7", size = 263514 }, - { url = "https://files.pythonhosted.org/packages/94/13/630690fe201f5502d2403dd3cfd451ed8858fe3c738ee88d095ad2ff407b/propcache-0.4.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1", size = 257781 }, - { url = "https://files.pythonhosted.org/packages/92/f7/1d4ec5841505f423469efbfc381d64b7b467438cd5a4bbcbb063f3b73d27/propcache-0.4.1-cp313-cp313t-win32.whl", hash = "sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717", size = 41396 }, - { url = "https://files.pythonhosted.org/packages/48/f0/615c30622316496d2cbbc29f5985f7777d3ada70f23370608c1d3e081c1f/propcache-0.4.1-cp313-cp313t-win_amd64.whl", hash = "sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37", size = 44897 }, - { url = "https://files.pythonhosted.org/packages/fd/ca/6002e46eccbe0e33dcd4069ef32f7f1c9e243736e07adca37ae8c4830ec3/propcache-0.4.1-cp313-cp313t-win_arm64.whl", hash = "sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a", size = 39789 }, - { url = "https://files.pythonhosted.org/packages/8e/5c/bca52d654a896f831b8256683457ceddd490ec18d9ec50e97dfd8fc726a8/propcache-0.4.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12", size = 78152 }, - { url = "https://files.pythonhosted.org/packages/65/9b/03b04e7d82a5f54fb16113d839f5ea1ede58a61e90edf515f6577c66fa8f/propcache-0.4.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c", size = 44869 }, - { url = "https://files.pythonhosted.org/packages/b2/fa/89a8ef0468d5833a23fff277b143d0573897cf75bd56670a6d28126c7d68/propcache-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded", size = 46596 }, - { url = "https://files.pythonhosted.org/packages/86/bd/47816020d337f4a746edc42fe8d53669965138f39ee117414c7d7a340cfe/propcache-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641", size = 206981 }, - { url = "https://files.pythonhosted.org/packages/df/f6/c5fa1357cc9748510ee55f37173eb31bfde6d94e98ccd9e6f033f2fc06e1/propcache-0.4.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4", size = 211490 }, - { url = "https://files.pythonhosted.org/packages/80/1e/e5889652a7c4a3846683401a48f0f2e5083ce0ec1a8a5221d8058fbd1adf/propcache-0.4.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44", size = 215371 }, - { url = "https://files.pythonhosted.org/packages/b2/f2/889ad4b2408f72fe1a4f6a19491177b30ea7bf1a0fd5f17050ca08cfc882/propcache-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d", size = 201424 }, - { url = "https://files.pythonhosted.org/packages/27/73/033d63069b57b0812c8bd19f311faebeceb6ba31b8f32b73432d12a0b826/propcache-0.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b", size = 197566 }, - { url = "https://files.pythonhosted.org/packages/dc/89/ce24f3dc182630b4e07aa6d15f0ff4b14ed4b9955fae95a0b54c58d66c05/propcache-0.4.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e", size = 193130 }, - { url = "https://files.pythonhosted.org/packages/a9/24/ef0d5fd1a811fb5c609278d0209c9f10c35f20581fcc16f818da959fc5b4/propcache-0.4.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f", size = 202625 }, - { url = "https://files.pythonhosted.org/packages/f5/02/98ec20ff5546f68d673df2f7a69e8c0d076b5abd05ca882dc7ee3a83653d/propcache-0.4.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49", size = 204209 }, - { url = "https://files.pythonhosted.org/packages/a0/87/492694f76759b15f0467a2a93ab68d32859672b646aa8a04ce4864e7932d/propcache-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144", size = 197797 }, - { url = "https://files.pythonhosted.org/packages/ee/36/66367de3575db1d2d3f3d177432bd14ee577a39d3f5d1b3d5df8afe3b6e2/propcache-0.4.1-cp314-cp314-win32.whl", hash = "sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f", size = 38140 }, - { url = "https://files.pythonhosted.org/packages/0c/2a/a758b47de253636e1b8aef181c0b4f4f204bf0dd964914fb2af90a95b49b/propcache-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153", size = 41257 }, - { url = "https://files.pythonhosted.org/packages/34/5e/63bd5896c3fec12edcbd6f12508d4890d23c265df28c74b175e1ef9f4f3b/propcache-0.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992", size = 38097 }, - { url = "https://files.pythonhosted.org/packages/99/85/9ff785d787ccf9bbb3f3106f79884a130951436f58392000231b4c737c80/propcache-0.4.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f", size = 81455 }, - { url = "https://files.pythonhosted.org/packages/90/85/2431c10c8e7ddb1445c1f7c4b54d886e8ad20e3c6307e7218f05922cad67/propcache-0.4.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393", size = 46372 }, - { url = "https://files.pythonhosted.org/packages/01/20/b0972d902472da9bcb683fa595099911f4d2e86e5683bcc45de60dd05dc3/propcache-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0", size = 48411 }, - { url = "https://files.pythonhosted.org/packages/e2/e3/7dc89f4f21e8f99bad3d5ddb3a3389afcf9da4ac69e3deb2dcdc96e74169/propcache-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a", size = 275712 }, - { url = "https://files.pythonhosted.org/packages/20/67/89800c8352489b21a8047c773067644e3897f02ecbbd610f4d46b7f08612/propcache-0.4.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be", size = 273557 }, - { url = "https://files.pythonhosted.org/packages/e2/a1/b52b055c766a54ce6d9c16d9aca0cad8059acd9637cdf8aa0222f4a026ef/propcache-0.4.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc", size = 280015 }, - { url = "https://files.pythonhosted.org/packages/48/c8/33cee30bd890672c63743049f3c9e4be087e6780906bfc3ec58528be59c1/propcache-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a", size = 262880 }, - { url = "https://files.pythonhosted.org/packages/0c/b1/8f08a143b204b418285c88b83d00edbd61afbc2c6415ffafc8905da7038b/propcache-0.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89", size = 260938 }, - { url = "https://files.pythonhosted.org/packages/cf/12/96e4664c82ca2f31e1c8dff86afb867348979eb78d3cb8546a680287a1e9/propcache-0.4.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726", size = 247641 }, - { url = "https://files.pythonhosted.org/packages/18/ed/e7a9cfca28133386ba52278136d42209d3125db08d0a6395f0cba0c0285c/propcache-0.4.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367", size = 262510 }, - { url = "https://files.pythonhosted.org/packages/f5/76/16d8bf65e8845dd62b4e2b57444ab81f07f40caa5652b8969b87ddcf2ef6/propcache-0.4.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36", size = 263161 }, - { url = "https://files.pythonhosted.org/packages/e7/70/c99e9edb5d91d5ad8a49fa3c1e8285ba64f1476782fed10ab251ff413ba1/propcache-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455", size = 257393 }, - { url = "https://files.pythonhosted.org/packages/08/02/87b25304249a35c0915d236575bc3574a323f60b47939a2262b77632a3ee/propcache-0.4.1-cp314-cp314t-win32.whl", hash = "sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85", size = 42546 }, - { url = "https://files.pythonhosted.org/packages/cb/ef/3c6ecf8b317aa982f309835e8f96987466123c6e596646d4e6a1dfcd080f/propcache-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1", size = 46259 }, - { url = "https://files.pythonhosted.org/packages/c4/2d/346e946d4951f37eca1e4f55be0f0174c52cd70720f84029b02f296f4a38/propcache-0.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9", size = 40428 }, - { url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305 }, -] - [[package]] name = "psycopg2-binary" version = "2.9.11" @@ -2181,74 +1611,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e1/36/9c0c326fe3a4227953dfb29f5d0c8ae3b8eb8c1cd2967aa569f50cb3c61f/psycopg2_binary-2.9.11-cp314-cp314-win_amd64.whl", hash = "sha256:4012c9c954dfaccd28f94e84ab9f94e12df76b4afb22331b1f0d3154893a6316", size = 2803913 }, ] -[[package]] -name = "ptyprocess" -version = "0.7.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993 }, -] - -[[package]] -name = "pure-eval" -version = "0.2.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42", size = 19752 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842 }, -] - -[[package]] -name = "pyarrow" -version = "22.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/30/53/04a7fdc63e6056116c9ddc8b43bc28c12cdd181b85cbeadb79278475f3ae/pyarrow-22.0.0.tar.gz", hash = "sha256:3d600dc583260d845c7d8a6db540339dd883081925da2bd1c5cb808f720b3cd9", size = 1151151 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2e/b7/18f611a8cdc43417f9394a3ccd3eace2f32183c08b9eddc3d17681819f37/pyarrow-22.0.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:3e294c5eadfb93d78b0763e859a0c16d4051fc1c5231ae8956d61cb0b5666f5a", size = 34272022 }, - { url = "https://files.pythonhosted.org/packages/26/5c/f259e2526c67eb4b9e511741b19870a02363a47a35edbebc55c3178db22d/pyarrow-22.0.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:69763ab2445f632d90b504a815a2a033f74332997052b721002298ed6de40f2e", size = 35995834 }, - { url = "https://files.pythonhosted.org/packages/50/8d/281f0f9b9376d4b7f146913b26fac0aa2829cd1ee7e997f53a27411bbb92/pyarrow-22.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:b41f37cabfe2463232684de44bad753d6be08a7a072f6a83447eeaf0e4d2a215", size = 45030348 }, - { url = "https://files.pythonhosted.org/packages/f5/e5/53c0a1c428f0976bf22f513d79c73000926cb00b9c138d8e02daf2102e18/pyarrow-22.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:35ad0f0378c9359b3f297299c3309778bb03b8612f987399a0333a560b43862d", size = 47699480 }, - { url = "https://files.pythonhosted.org/packages/95/e1/9dbe4c465c3365959d183e6345d0a8d1dc5b02ca3f8db4760b3bc834cf25/pyarrow-22.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8382ad21458075c2e66a82a29d650f963ce51c7708c7c0ff313a8c206c4fd5e8", size = 48011148 }, - { url = "https://files.pythonhosted.org/packages/c5/b4/7caf5d21930061444c3cf4fa7535c82faf5263e22ce43af7c2759ceb5b8b/pyarrow-22.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1a812a5b727bc09c3d7ea072c4eebf657c2f7066155506ba31ebf4792f88f016", size = 50276964 }, - { url = "https://files.pythonhosted.org/packages/ae/f3/cec89bd99fa3abf826f14d4e53d3d11340ce6f6af4d14bdcd54cd83b6576/pyarrow-22.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:ec5d40dd494882704fb876c16fa7261a69791e784ae34e6b5992e977bd2e238c", size = 28106517 }, - { url = "https://files.pythonhosted.org/packages/af/63/ba23862d69652f85b615ca14ad14f3bcfc5bf1b99ef3f0cd04ff93fdad5a/pyarrow-22.0.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:bea79263d55c24a32b0d79c00a1c58bb2ee5f0757ed95656b01c0fb310c5af3d", size = 34211578 }, - { url = "https://files.pythonhosted.org/packages/b1/d0/f9ad86fe809efd2bcc8be32032fa72e8b0d112b01ae56a053006376c5930/pyarrow-22.0.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:12fe549c9b10ac98c91cf791d2945e878875d95508e1a5d14091a7aaa66d9cf8", size = 35989906 }, - { url = "https://files.pythonhosted.org/packages/b4/a8/f910afcb14630e64d673f15904ec27dd31f1e009b77033c365c84e8c1e1d/pyarrow-22.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:334f900ff08ce0423407af97e6c26ad5d4e3b0763645559ece6fbf3747d6a8f5", size = 45021677 }, - { url = "https://files.pythonhosted.org/packages/13/95/aec81f781c75cd10554dc17a25849c720d54feafb6f7847690478dcf5ef8/pyarrow-22.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:c6c791b09c57ed76a18b03f2631753a4960eefbbca80f846da8baefc6491fcfe", size = 47726315 }, - { url = "https://files.pythonhosted.org/packages/bb/d4/74ac9f7a54cfde12ee42734ea25d5a3c9a45db78f9def949307a92720d37/pyarrow-22.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c3200cb41cdbc65156e5f8c908d739b0dfed57e890329413da2748d1a2cd1a4e", size = 47990906 }, - { url = "https://files.pythonhosted.org/packages/2e/71/fedf2499bf7a95062eafc989ace56572f3343432570e1c54e6599d5b88da/pyarrow-22.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ac93252226cf288753d8b46280f4edf3433bf9508b6977f8dd8526b521a1bbb9", size = 50306783 }, - { url = "https://files.pythonhosted.org/packages/68/ed/b202abd5a5b78f519722f3d29063dda03c114711093c1995a33b8e2e0f4b/pyarrow-22.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:44729980b6c50a5f2bfcc2668d36c569ce17f8b17bccaf470c4313dcbbf13c9d", size = 27972883 }, - { url = "https://files.pythonhosted.org/packages/a6/d6/d0fac16a2963002fc22c8fa75180a838737203d558f0ed3b564c4a54eef5/pyarrow-22.0.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:e6e95176209257803a8b3d0394f21604e796dadb643d2f7ca21b66c9c0b30c9a", size = 34204629 }, - { url = "https://files.pythonhosted.org/packages/c6/9c/1d6357347fbae062ad3f17082f9ebc29cc733321e892c0d2085f42a2212b/pyarrow-22.0.0-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:001ea83a58024818826a9e3f89bf9310a114f7e26dfe404a4c32686f97bd7901", size = 35985783 }, - { url = "https://files.pythonhosted.org/packages/ff/c0/782344c2ce58afbea010150df07e3a2f5fdad299cd631697ae7bd3bac6e3/pyarrow-22.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:ce20fe000754f477c8a9125543f1936ea5b8867c5406757c224d745ed033e691", size = 45020999 }, - { url = "https://files.pythonhosted.org/packages/1b/8b/5362443737a5307a7b67c1017c42cd104213189b4970bf607e05faf9c525/pyarrow-22.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e0a15757fccb38c410947df156f9749ae4a3c89b2393741a50521f39a8cf202a", size = 47724601 }, - { url = "https://files.pythonhosted.org/packages/69/4d/76e567a4fc2e190ee6072967cb4672b7d9249ac59ae65af2d7e3047afa3b/pyarrow-22.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cedb9dd9358e4ea1d9bce3665ce0797f6adf97ff142c8e25b46ba9cdd508e9b6", size = 48001050 }, - { url = "https://files.pythonhosted.org/packages/01/5e/5653f0535d2a1aef8223cee9d92944cb6bccfee5cf1cd3f462d7cb022790/pyarrow-22.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:252be4a05f9d9185bb8c18e83764ebcfea7185076c07a7a662253af3a8c07941", size = 50307877 }, - { url = "https://files.pythonhosted.org/packages/2d/f8/1d0bd75bf9328a3b826e24a16e5517cd7f9fbf8d34a3184a4566ef5a7f29/pyarrow-22.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:a4893d31e5ef780b6edcaf63122df0f8d321088bb0dee4c8c06eccb1ca28d145", size = 27977099 }, - { url = "https://files.pythonhosted.org/packages/90/81/db56870c997805bf2b0f6eeeb2d68458bf4654652dccdcf1bf7a42d80903/pyarrow-22.0.0-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:f7fe3dbe871294ba70d789be16b6e7e52b418311e166e0e3cba9522f0f437fb1", size = 34336685 }, - { url = "https://files.pythonhosted.org/packages/1c/98/0727947f199aba8a120f47dfc229eeb05df15bcd7a6f1b669e9f882afc58/pyarrow-22.0.0-cp313-cp313t-macosx_12_0_x86_64.whl", hash = "sha256:ba95112d15fd4f1105fb2402c4eab9068f0554435e9b7085924bcfaac2cc306f", size = 36032158 }, - { url = "https://files.pythonhosted.org/packages/96/b4/9babdef9c01720a0785945c7cf550e4acd0ebcd7bdd2e6f0aa7981fa85e2/pyarrow-22.0.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:c064e28361c05d72eed8e744c9605cbd6d2bb7481a511c74071fd9b24bc65d7d", size = 44892060 }, - { url = "https://files.pythonhosted.org/packages/f8/ca/2f8804edd6279f78a37062d813de3f16f29183874447ef6d1aadbb4efa0f/pyarrow-22.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:6f9762274496c244d951c819348afbcf212714902742225f649cf02823a6a10f", size = 47504395 }, - { url = "https://files.pythonhosted.org/packages/b9/f0/77aa5198fd3943682b2e4faaf179a674f0edea0d55d326d83cb2277d9363/pyarrow-22.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a9d9ffdc2ab696f6b15b4d1f7cec6658e1d788124418cb30030afbae31c64746", size = 48066216 }, - { url = "https://files.pythonhosted.org/packages/79/87/a1937b6e78b2aff18b706d738c9e46ade5bfcf11b294e39c87706a0089ac/pyarrow-22.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ec1a15968a9d80da01e1d30349b2b0d7cc91e96588ee324ce1b5228175043e95", size = 50288552 }, - { url = "https://files.pythonhosted.org/packages/60/ae/b5a5811e11f25788ccfdaa8f26b6791c9807119dffcf80514505527c384c/pyarrow-22.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:bba208d9c7decf9961998edf5c65e3ea4355d5818dd6cd0f6809bec1afb951cc", size = 28262504 }, - { url = "https://files.pythonhosted.org/packages/bd/b0/0fa4d28a8edb42b0a7144edd20befd04173ac79819547216f8a9f36f9e50/pyarrow-22.0.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:9bddc2cade6561f6820d4cd73f99a0243532ad506bc510a75a5a65a522b2d74d", size = 34224062 }, - { url = "https://files.pythonhosted.org/packages/0f/a8/7a719076b3c1be0acef56a07220c586f25cd24de0e3f3102b438d18ae5df/pyarrow-22.0.0-cp314-cp314-macosx_12_0_x86_64.whl", hash = "sha256:e70ff90c64419709d38c8932ea9fe1cc98415c4f87ea8da81719e43f02534bc9", size = 35990057 }, - { url = "https://files.pythonhosted.org/packages/89/3c/359ed54c93b47fb6fe30ed16cdf50e3f0e8b9ccfb11b86218c3619ae50a8/pyarrow-22.0.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:92843c305330aa94a36e706c16209cd4df274693e777ca47112617db7d0ef3d7", size = 45068002 }, - { url = "https://files.pythonhosted.org/packages/55/fc/4945896cc8638536ee787a3bd6ce7cec8ec9acf452d78ec39ab328efa0a1/pyarrow-22.0.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:6dda1ddac033d27421c20d7a7943eec60be44e0db4e079f33cc5af3b8280ccde", size = 47737765 }, - { url = "https://files.pythonhosted.org/packages/cd/5e/7cb7edeb2abfaa1f79b5d5eb89432356155c8426f75d3753cbcb9592c0fd/pyarrow-22.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:84378110dd9a6c06323b41b56e129c504d157d1a983ce8f5443761eb5256bafc", size = 48048139 }, - { url = "https://files.pythonhosted.org/packages/88/c6/546baa7c48185f5e9d6e59277c4b19f30f48c94d9dd938c2a80d4d6b067c/pyarrow-22.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:854794239111d2b88b40b6ef92aa478024d1e5074f364033e73e21e3f76b25e0", size = 50314244 }, - { url = "https://files.pythonhosted.org/packages/3c/79/755ff2d145aafec8d347bf18f95e4e81c00127f06d080135dfc86aea417c/pyarrow-22.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:b883fe6fd85adad7932b3271c38ac289c65b7337c2c132e9569f9d3940620730", size = 28757501 }, - { url = "https://files.pythonhosted.org/packages/0e/d2/237d75ac28ced3147912954e3c1a174df43a95f4f88e467809118a8165e0/pyarrow-22.0.0-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:7a820d8ae11facf32585507c11f04e3f38343c1e784c9b5a8b1da5c930547fe2", size = 34355506 }, - { url = "https://files.pythonhosted.org/packages/1e/2c/733dfffe6d3069740f98e57ff81007809067d68626c5faef293434d11bd6/pyarrow-22.0.0-cp314-cp314t-macosx_12_0_x86_64.whl", hash = "sha256:c6ec3675d98915bf1ec8b3c7986422682f7232ea76cad276f4c8abd5b7319b70", size = 36047312 }, - { url = "https://files.pythonhosted.org/packages/7c/2b/29d6e3782dc1f299727462c1543af357a0f2c1d3c160ce199950d9ca51eb/pyarrow-22.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:3e739edd001b04f654b166204fc7a9de896cf6007eaff33409ee9e50ceaff754", size = 45081609 }, - { url = "https://files.pythonhosted.org/packages/8d/42/aa9355ecc05997915af1b7b947a7f66c02dcaa927f3203b87871c114ba10/pyarrow-22.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:7388ac685cab5b279a41dfe0a6ccd99e4dbf322edfb63e02fc0443bf24134e91", size = 47703663 }, - { url = "https://files.pythonhosted.org/packages/ee/62/45abedde480168e83a1de005b7b7043fd553321c1e8c5a9a114425f64842/pyarrow-22.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:f633074f36dbc33d5c05b5dc75371e5660f1dbf9c8b1d95669def05e5425989c", size = 48066543 }, - { url = "https://files.pythonhosted.org/packages/84/e9/7878940a5b072e4f3bf998770acafeae13b267f9893af5f6d4ab3904b67e/pyarrow-22.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:4c19236ae2402a8663a2c8f21f1870a03cc57f0bef7e4b6eb3238cc82944de80", size = 50288838 }, - { url = "https://files.pythonhosted.org/packages/7b/03/f335d6c52b4a4761bcc83499789a1e2e16d9d201a58c327a9b5cc9a41bd9/pyarrow-22.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0c34fe18094686194f204a3b1787a27456897d8a2d62caf84b61e8dfbc0252ae", size = 29185594 }, -] - [[package]] name = "pydantic" version = "2.12.3" @@ -2425,29 +1787,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl", hash = "sha256:b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61", size = 21230 }, ] -[[package]] -name = "pytz" -version = "2025.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225 }, -] - -[[package]] -name = "pyvis" -version = "0.3.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "ipython" }, - { name = "jinja2" }, - { name = "jsonpickle" }, - { name = "networkx" }, -] -wheels = [ - { url = "https://files.pythonhosted.org/packages/ab/4b/e37e4e5d5ee1179694917b445768bdbfb084f5a59ecd38089d3413d4c70f/pyvis-0.3.2-py3-none-any.whl", hash = "sha256:5720c4ca8161dc5d9ab352015723abb7a8bb8fb443edeb07f7a322db34a97555", size = 756038 }, -] - [[package]] name = "pyyaml" version = "6.0.3" @@ -2610,6 +1949,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738 }, ] +[[package]] +name = "requests-toolbelt" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f3/61/d7545dafb7ac2230c70d38d31cbfe4cc64f7144dc41f6e4e4b78ecd9f5bb/requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6", size = 206888 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06", size = 54481 }, +] + [[package]] name = "rich" version = "14.2.0" @@ -2922,20 +2273,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3a/e2/745aeba88a8513017fbac2fd2f9f07b8a36065e51695f818541eb795ec0c/srsly-2.5.1-cp313-cp313-win_amd64.whl", hash = "sha256:e73712be1634b5e1de6f81c273a7d47fe091ad3c79dc779c03d3416a5c117cee", size = 630634 }, ] -[[package]] -name = "stack-data" -version = "0.6.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "asttokens" }, - { name = "executing" }, - { name = "pure-eval" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", size = 44707 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521 }, -] - [[package]] name = "sympy" version = "1.14.0" @@ -2948,6 +2285,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353 }, ] +[[package]] +name = "tenacity" +version = "9.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0a/d4/2b0cd0fe285e14b36db076e78c93766ff1d529d70408bd1d2a5a84f1d929/tenacity-9.1.2.tar.gz", hash = "sha256:1169d376c297e7de388d18b4481760d478b0e99a777cad3a9c86e556f4b697cb", size = 48036 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/30/643397144bfbfec6f6ef821f36f33e57d35946c44a2352d3c9f0ae847619/tenacity-9.1.2-py3-none-any.whl", hash = "sha256:f77bf36710d8b73a50b2dd155c97b870017ad21afe6ab300326b0371b3b05138", size = 28248 }, +] + [[package]] name = "thinc" version = "8.3.6" @@ -3093,15 +2439,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540 }, ] -[[package]] -name = "traitlets" -version = "5.14.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/eb/79/72064e6a701c2183016abbbfedaba506d81e30e232a68c9f0d6f6fcd1574/traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7", size = 161621 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359 }, -] - [[package]] name = "transformers" version = "4.57.1" @@ -3172,15 +2509,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611 }, ] -[[package]] -name = "tzdata" -version = "2025.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839 }, -] - [[package]] name = "urllib3" version = "2.5.0" @@ -3202,15 +2530,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/06/7c/34330a89da55610daa5f245ddce5aab81244321101614751e7537f125133/wasabi-1.1.3-py3-none-any.whl", hash = "sha256:f76e16e8f7e79f8c4c8be49b4024ac725713ab10cd7f19350ad18a8e3f71728c", size = 27880 }, ] -[[package]] -name = "wcwidth" -version = "0.2.14" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/24/30/6b0809f4510673dc723187aeaf24c7f5459922d01e2f794277a3dfb90345/wcwidth-0.2.14.tar.gz", hash = "sha256:4d478375d31bc5395a3c55c40ccdf3354688364cd61c4f6adacaa9215d0b3605", size = 102293 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/af/b5/123f13c975e9f27ab9c0770f514345bd406d0e8d3b7a0723af9d43f710af/wcwidth-0.2.14-py2.py3-none-any.whl", hash = "sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1", size = 37286 }, -] - [[package]] name = "weasel" version = "0.4.1" @@ -3313,214 +2632,75 @@ wheels = [ ] [[package]] -name = "xxhash" -version = "3.6.0" +name = "zstandard" +version = "0.25.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/02/84/30869e01909fb37a6cc7e18688ee8bf1e42d57e7e0777636bd47524c43c7/xxhash-3.6.0.tar.gz", hash = "sha256:f0162a78b13a0d7617b2845b90c763339d1f1d82bb04a4b07f4ab535cc5e05d6", size = 85160 } +sdist = { url = "https://files.pythonhosted.org/packages/fd/aa/3e0508d5a5dd96529cdc5a97011299056e14c6505b678fd58938792794b1/zstandard-0.25.0.tar.gz", hash = "sha256:7713e1179d162cf5c7906da876ec2ccb9c3a9dcbdffef0cc7f70c3667a205f0b", size = 711513 } wheels = [ - { url = "https://files.pythonhosted.org/packages/17/d4/cc2f0400e9154df4b9964249da78ebd72f318e35ccc425e9f403c392f22a/xxhash-3.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b47bbd8cf2d72797f3c2772eaaac0ded3d3af26481a26d7d7d41dc2d3c46b04a", size = 32844 }, - { url = "https://files.pythonhosted.org/packages/5e/ec/1cc11cd13e26ea8bc3cb4af4eaadd8d46d5014aebb67be3f71fb0b68802a/xxhash-3.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2b6821e94346f96db75abaa6e255706fb06ebd530899ed76d32cd99f20dc52fa", size = 30809 }, - { url = "https://files.pythonhosted.org/packages/04/5f/19fe357ea348d98ca22f456f75a30ac0916b51c753e1f8b2e0e6fb884cce/xxhash-3.6.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d0a9751f71a1a65ce3584e9cae4467651c7e70c9d31017fa57574583a4540248", size = 194665 }, - { url = "https://files.pythonhosted.org/packages/90/3b/d1f1a8f5442a5fd8beedae110c5af7604dc37349a8e16519c13c19a9a2de/xxhash-3.6.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b29ee68625ab37b04c0b40c3fafdf24d2f75ccd778333cfb698f65f6c463f62", size = 213550 }, - { url = "https://files.pythonhosted.org/packages/c4/ef/3a9b05eb527457d5db13a135a2ae1a26c80fecd624d20f3e8dcc4cb170f3/xxhash-3.6.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6812c25fe0d6c36a46ccb002f40f27ac903bf18af9f6dd8f9669cb4d176ab18f", size = 212384 }, - { url = "https://files.pythonhosted.org/packages/0f/18/ccc194ee698c6c623acbf0f8c2969811a8a4b6185af5e824cd27b9e4fd3e/xxhash-3.6.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4ccbff013972390b51a18ef1255ef5ac125c92dc9143b2d1909f59abc765540e", size = 445749 }, - { url = "https://files.pythonhosted.org/packages/a5/86/cf2c0321dc3940a7aa73076f4fd677a0fb3e405cb297ead7d864fd90847e/xxhash-3.6.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:297b7fbf86c82c550e12e8fb71968b3f033d27b874276ba3624ea868c11165a8", size = 193880 }, - { url = "https://files.pythonhosted.org/packages/82/fb/96213c8560e6f948a1ecc9a7613f8032b19ee45f747f4fca4eb31bb6d6ed/xxhash-3.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:dea26ae1eb293db089798d3973a5fc928a18fdd97cc8801226fae705b02b14b0", size = 210912 }, - { url = "https://files.pythonhosted.org/packages/40/aa/4395e669b0606a096d6788f40dbdf2b819d6773aa290c19e6e83cbfc312f/xxhash-3.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7a0b169aafb98f4284f73635a8e93f0735f9cbde17bd5ec332480484241aaa77", size = 198654 }, - { url = "https://files.pythonhosted.org/packages/67/74/b044fcd6b3d89e9b1b665924d85d3f400636c23590226feb1eb09e1176ce/xxhash-3.6.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:08d45aef063a4531b785cd72de4887766d01dc8f362a515693df349fdb825e0c", size = 210867 }, - { url = "https://files.pythonhosted.org/packages/bc/fd/3ce73bf753b08cb19daee1eb14aa0d7fe331f8da9c02dd95316ddfe5275e/xxhash-3.6.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:929142361a48ee07f09121fe9e96a84950e8d4df3bb298ca5d88061969f34d7b", size = 414012 }, - { url = "https://files.pythonhosted.org/packages/ba/b3/5a4241309217c5c876f156b10778f3ab3af7ba7e3259e6d5f5c7d0129eb2/xxhash-3.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:51312c768403d8540487dbbfb557454cfc55589bbde6424456951f7fcd4facb3", size = 191409 }, - { url = "https://files.pythonhosted.org/packages/c0/01/99bfbc15fb9abb9a72b088c1d95219fc4782b7d01fc835bd5744d66dd0b8/xxhash-3.6.0-cp311-cp311-win32.whl", hash = "sha256:d1927a69feddc24c987b337ce81ac15c4720955b667fe9b588e02254b80446fd", size = 30574 }, - { url = "https://files.pythonhosted.org/packages/65/79/9d24d7f53819fe301b231044ea362ce64e86c74f6e8c8e51320de248b3e5/xxhash-3.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:26734cdc2d4ffe449b41d186bbeac416f704a482ed835d375a5c0cb02bc63fef", size = 31481 }, - { url = "https://files.pythonhosted.org/packages/30/4e/15cd0e3e8772071344eab2961ce83f6e485111fed8beb491a3f1ce100270/xxhash-3.6.0-cp311-cp311-win_arm64.whl", hash = "sha256:d72f67ef8bf36e05f5b6c65e8524f265bd61071471cd4cf1d36743ebeeeb06b7", size = 27861 }, - { url = "https://files.pythonhosted.org/packages/9a/07/d9412f3d7d462347e4511181dea65e47e0d0e16e26fbee2ea86a2aefb657/xxhash-3.6.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:01362c4331775398e7bb34e3ab403bc9ee9f7c497bc7dee6272114055277dd3c", size = 32744 }, - { url = "https://files.pythonhosted.org/packages/79/35/0429ee11d035fc33abe32dca1b2b69e8c18d236547b9a9b72c1929189b9a/xxhash-3.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b7b2df81a23f8cb99656378e72501b2cb41b1827c0f5a86f87d6b06b69f9f204", size = 30816 }, - { url = "https://files.pythonhosted.org/packages/b7/f2/57eb99aa0f7d98624c0932c5b9a170e1806406cdbcdb510546634a1359e0/xxhash-3.6.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:dc94790144e66b14f67b10ac8ed75b39ca47536bf8800eb7c24b50271ea0c490", size = 194035 }, - { url = "https://files.pythonhosted.org/packages/4c/ed/6224ba353690d73af7a3f1c7cdb1fc1b002e38f783cb991ae338e1eb3d79/xxhash-3.6.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:93f107c673bccf0d592cdba077dedaf52fe7f42dcd7676eba1f6d6f0c3efffd2", size = 212914 }, - { url = "https://files.pythonhosted.org/packages/38/86/fb6b6130d8dd6b8942cc17ab4d90e223653a89aa32ad2776f8af7064ed13/xxhash-3.6.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2aa5ee3444c25b69813663c9f8067dcfaa2e126dc55e8dddf40f4d1c25d7effa", size = 212163 }, - { url = "https://files.pythonhosted.org/packages/ee/dc/e84875682b0593e884ad73b2d40767b5790d417bde603cceb6878901d647/xxhash-3.6.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f7f99123f0e1194fa59cc69ad46dbae2e07becec5df50a0509a808f90a0f03f0", size = 445411 }, - { url = "https://files.pythonhosted.org/packages/11/4f/426f91b96701ec2f37bb2b8cec664eff4f658a11f3fa9d94f0a887ea6d2b/xxhash-3.6.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:49e03e6fe2cac4a1bc64952dd250cf0dbc5ef4ebb7b8d96bce82e2de163c82a2", size = 193883 }, - { url = "https://files.pythonhosted.org/packages/53/5a/ddbb83eee8e28b778eacfc5a85c969673e4023cdeedcfcef61f36731610b/xxhash-3.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bd17fede52a17a4f9a7bc4472a5867cb0b160deeb431795c0e4abe158bc784e9", size = 210392 }, - { url = "https://files.pythonhosted.org/packages/1e/c2/ff69efd07c8c074ccdf0a4f36fcdd3d27363665bcdf4ba399abebe643465/xxhash-3.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:6fb5f5476bef678f69db04f2bd1efbed3030d2aba305b0fc1773645f187d6a4e", size = 197898 }, - { url = "https://files.pythonhosted.org/packages/58/ca/faa05ac19b3b622c7c9317ac3e23954187516298a091eb02c976d0d3dd45/xxhash-3.6.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:843b52f6d88071f87eba1631b684fcb4b2068cd2180a0224122fe4ef011a9374", size = 210655 }, - { url = "https://files.pythonhosted.org/packages/d4/7a/06aa7482345480cc0cb597f5c875b11a82c3953f534394f620b0be2f700c/xxhash-3.6.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:7d14a6cfaf03b1b6f5f9790f76880601ccc7896aff7ab9cd8978a939c1eb7e0d", size = 414001 }, - { url = "https://files.pythonhosted.org/packages/23/07/63ffb386cd47029aa2916b3d2f454e6cc5b9f5c5ada3790377d5430084e7/xxhash-3.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:418daf3db71e1413cfe211c2f9a528456936645c17f46b5204705581a45390ae", size = 191431 }, - { url = "https://files.pythonhosted.org/packages/0f/93/14fde614cadb4ddf5e7cebf8918b7e8fac5ae7861c1875964f17e678205c/xxhash-3.6.0-cp312-cp312-win32.whl", hash = "sha256:50fc255f39428a27299c20e280d6193d8b63b8ef8028995323bf834a026b4fbb", size = 30617 }, - { url = "https://files.pythonhosted.org/packages/13/5d/0d125536cbe7565a83d06e43783389ecae0c0f2ed037b48ede185de477c0/xxhash-3.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:c0f2ab8c715630565ab8991b536ecded9416d615538be8ecddce43ccf26cbc7c", size = 31534 }, - { url = "https://files.pythonhosted.org/packages/54/85/6ec269b0952ec7e36ba019125982cf11d91256a778c7c3f98a4c5043d283/xxhash-3.6.0-cp312-cp312-win_arm64.whl", hash = "sha256:eae5c13f3bc455a3bbb68bdc513912dc7356de7e2280363ea235f71f54064829", size = 27876 }, - { url = "https://files.pythonhosted.org/packages/33/76/35d05267ac82f53ae9b0e554da7c5e281ee61f3cad44c743f0fcd354f211/xxhash-3.6.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:599e64ba7f67472481ceb6ee80fa3bd828fd61ba59fb11475572cc5ee52b89ec", size = 32738 }, - { url = "https://files.pythonhosted.org/packages/31/a8/3fbce1cd96534a95e35d5120637bf29b0d7f5d8fa2f6374e31b4156dd419/xxhash-3.6.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7d8b8aaa30fca4f16f0c84a5c8d7ddee0e25250ec2796c973775373257dde8f1", size = 30821 }, - { url = "https://files.pythonhosted.org/packages/0c/ea/d387530ca7ecfa183cb358027f1833297c6ac6098223fd14f9782cd0015c/xxhash-3.6.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d597acf8506d6e7101a4a44a5e428977a51c0fadbbfd3c39650cca9253f6e5a6", size = 194127 }, - { url = "https://files.pythonhosted.org/packages/ba/0c/71435dcb99874b09a43b8d7c54071e600a7481e42b3e3ce1eb5226a5711a/xxhash-3.6.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:858dc935963a33bc33490128edc1c12b0c14d9c7ebaa4e387a7869ecc4f3e263", size = 212975 }, - { url = "https://files.pythonhosted.org/packages/84/7a/c2b3d071e4bb4a90b7057228a99b10d51744878f4a8a6dd643c8bd897620/xxhash-3.6.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ba284920194615cb8edf73bf52236ce2e1664ccd4a38fdb543506413529cc546", size = 212241 }, - { url = "https://files.pythonhosted.org/packages/81/5f/640b6eac0128e215f177df99eadcd0f1b7c42c274ab6a394a05059694c5a/xxhash-3.6.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4b54219177f6c6674d5378bd862c6aedf64725f70dd29c472eaae154df1a2e89", size = 445471 }, - { url = "https://files.pythonhosted.org/packages/5e/1e/3c3d3ef071b051cc3abbe3721ffb8365033a172613c04af2da89d5548a87/xxhash-3.6.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:42c36dd7dbad2f5238950c377fcbf6811b1cdb1c444fab447960030cea60504d", size = 193936 }, - { url = "https://files.pythonhosted.org/packages/2c/bd/4a5f68381939219abfe1c22a9e3a5854a4f6f6f3c4983a87d255f21f2e5d/xxhash-3.6.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f22927652cba98c44639ffdc7aaf35828dccf679b10b31c4ad72a5b530a18eb7", size = 210440 }, - { url = "https://files.pythonhosted.org/packages/eb/37/b80fe3d5cfb9faff01a02121a0f4d565eb7237e9e5fc66e73017e74dcd36/xxhash-3.6.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b45fad44d9c5c119e9c6fbf2e1c656a46dc68e280275007bbfd3d572b21426db", size = 197990 }, - { url = "https://files.pythonhosted.org/packages/d7/fd/2c0a00c97b9e18f72e1f240ad4e8f8a90fd9d408289ba9c7c495ed7dc05c/xxhash-3.6.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:6f2580ffab1a8b68ef2b901cde7e55fa8da5e4be0977c68f78fc80f3c143de42", size = 210689 }, - { url = "https://files.pythonhosted.org/packages/93/86/5dd8076a926b9a95db3206aba20d89a7fc14dd5aac16e5c4de4b56033140/xxhash-3.6.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:40c391dd3cd041ebc3ffe6f2c862f402e306eb571422e0aa918d8070ba31da11", size = 414068 }, - { url = "https://files.pythonhosted.org/packages/af/3c/0bb129170ee8f3650f08e993baee550a09593462a5cddd8e44d0011102b1/xxhash-3.6.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f205badabde7aafd1a31e8ca2a3e5a763107a71c397c4481d6a804eb5063d8bd", size = 191495 }, - { url = "https://files.pythonhosted.org/packages/e9/3a/6797e0114c21d1725e2577508e24006fd7ff1d8c0c502d3b52e45c1771d8/xxhash-3.6.0-cp313-cp313-win32.whl", hash = "sha256:2577b276e060b73b73a53042ea5bd5203d3e6347ce0d09f98500f418a9fcf799", size = 30620 }, - { url = "https://files.pythonhosted.org/packages/86/15/9bc32671e9a38b413a76d24722a2bf8784a132c043063a8f5152d390b0f9/xxhash-3.6.0-cp313-cp313-win_amd64.whl", hash = "sha256:757320d45d2fbcce8f30c42a6b2f47862967aea7bf458b9625b4bbe7ee390392", size = 31542 }, - { url = "https://files.pythonhosted.org/packages/39/c5/cc01e4f6188656e56112d6a8e0dfe298a16934b8c47a247236549a3f7695/xxhash-3.6.0-cp313-cp313-win_arm64.whl", hash = "sha256:457b8f85dec5825eed7b69c11ae86834a018b8e3df5e77783c999663da2f96d6", size = 27880 }, - { url = "https://files.pythonhosted.org/packages/f3/30/25e5321c8732759e930c555176d37e24ab84365482d257c3b16362235212/xxhash-3.6.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a42e633d75cdad6d625434e3468126c73f13f7584545a9cf34e883aa1710e702", size = 32956 }, - { url = "https://files.pythonhosted.org/packages/9f/3c/0573299560d7d9f8ab1838f1efc021a280b5ae5ae2e849034ef3dee18810/xxhash-3.6.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:568a6d743219e717b07b4e03b0a828ce593833e498c3b64752e0f5df6bfe84db", size = 31072 }, - { url = "https://files.pythonhosted.org/packages/7a/1c/52d83a06e417cd9d4137722693424885cc9878249beb3a7c829e74bf7ce9/xxhash-3.6.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:bec91b562d8012dae276af8025a55811b875baace6af510412a5e58e3121bc54", size = 196409 }, - { url = "https://files.pythonhosted.org/packages/e3/8e/c6d158d12a79bbd0b878f8355432075fc82759e356ab5a111463422a239b/xxhash-3.6.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:78e7f2f4c521c30ad5e786fdd6bae89d47a32672a80195467b5de0480aa97b1f", size = 215736 }, - { url = "https://files.pythonhosted.org/packages/bc/68/c4c80614716345d55071a396cf03d06e34b5f4917a467faf43083c995155/xxhash-3.6.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3ed0df1b11a79856df5ffcab572cbd6b9627034c1c748c5566fa79df9048a7c5", size = 214833 }, - { url = "https://files.pythonhosted.org/packages/7e/e9/ae27c8ffec8b953efa84c7c4a6c6802c263d587b9fc0d6e7cea64e08c3af/xxhash-3.6.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0e4edbfc7d420925b0dd5e792478ed393d6e75ff8fc219a6546fb446b6a417b1", size = 448348 }, - { url = "https://files.pythonhosted.org/packages/d7/6b/33e21afb1b5b3f46b74b6bd1913639066af218d704cc0941404ca717fc57/xxhash-3.6.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fba27a198363a7ef87f8c0f6b171ec36b674fe9053742c58dd7e3201c1ab30ee", size = 196070 }, - { url = "https://files.pythonhosted.org/packages/96/b6/fcabd337bc5fa624e7203aa0fa7d0c49eed22f72e93229431752bddc83d9/xxhash-3.6.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:794fe9145fe60191c6532fa95063765529770edcdd67b3d537793e8004cabbfd", size = 212907 }, - { url = "https://files.pythonhosted.org/packages/4b/d3/9ee6160e644d660fcf176c5825e61411c7f62648728f69c79ba237250143/xxhash-3.6.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:6105ef7e62b5ac73a837778efc331a591d8442f8ef5c7e102376506cb4ae2729", size = 200839 }, - { url = "https://files.pythonhosted.org/packages/0d/98/e8de5baa5109394baf5118f5e72ab21a86387c4f89b0e77ef3e2f6b0327b/xxhash-3.6.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:f01375c0e55395b814a679b3eea205db7919ac2af213f4a6682e01220e5fe292", size = 213304 }, - { url = "https://files.pythonhosted.org/packages/7b/1d/71056535dec5c3177eeb53e38e3d367dd1d16e024e63b1cee208d572a033/xxhash-3.6.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:d706dca2d24d834a4661619dcacf51a75c16d65985718d6a7d73c1eeeb903ddf", size = 416930 }, - { url = "https://files.pythonhosted.org/packages/dc/6c/5cbde9de2cd967c322e651c65c543700b19e7ae3e0aae8ece3469bf9683d/xxhash-3.6.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5f059d9faeacd49c0215d66f4056e1326c80503f51a1532ca336a385edadd033", size = 193787 }, - { url = "https://files.pythonhosted.org/packages/19/fa/0172e350361d61febcea941b0cc541d6e6c8d65d153e85f850a7b256ff8a/xxhash-3.6.0-cp313-cp313t-win32.whl", hash = "sha256:1244460adc3a9be84731d72b8e80625788e5815b68da3da8b83f78115a40a7ec", size = 30916 }, - { url = "https://files.pythonhosted.org/packages/ad/e6/e8cf858a2b19d6d45820f072eff1bea413910592ff17157cabc5f1227a16/xxhash-3.6.0-cp313-cp313t-win_amd64.whl", hash = "sha256:b1e420ef35c503869c4064f4a2f2b08ad6431ab7b229a05cce39d74268bca6b8", size = 31799 }, - { url = "https://files.pythonhosted.org/packages/56/15/064b197e855bfb7b343210e82490ae672f8bc7cdf3ddb02e92f64304ee8a/xxhash-3.6.0-cp313-cp313t-win_arm64.whl", hash = "sha256:ec44b73a4220623235f67a996c862049f375df3b1052d9899f40a6382c32d746", size = 28044 }, - { url = "https://files.pythonhosted.org/packages/7e/5e/0138bc4484ea9b897864d59fce9be9086030825bc778b76cb5a33a906d37/xxhash-3.6.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:a40a3d35b204b7cc7643cbcf8c9976d818cb47befcfac8bbefec8038ac363f3e", size = 32754 }, - { url = "https://files.pythonhosted.org/packages/18/d7/5dac2eb2ec75fd771957a13e5dda560efb2176d5203f39502a5fc571f899/xxhash-3.6.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a54844be970d3fc22630b32d515e79a90d0a3ddb2644d8d7402e3c4c8da61405", size = 30846 }, - { url = "https://files.pythonhosted.org/packages/fe/71/8bc5be2bb00deb5682e92e8da955ebe5fa982da13a69da5a40a4c8db12fb/xxhash-3.6.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:016e9190af8f0a4e3741343777710e3d5717427f175adfdc3e72508f59e2a7f3", size = 194343 }, - { url = "https://files.pythonhosted.org/packages/e7/3b/52badfb2aecec2c377ddf1ae75f55db3ba2d321c5e164f14461c90837ef3/xxhash-3.6.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4f6f72232f849eb9d0141e2ebe2677ece15adfd0fa599bc058aad83c714bb2c6", size = 213074 }, - { url = "https://files.pythonhosted.org/packages/a2/2b/ae46b4e9b92e537fa30d03dbc19cdae57ed407e9c26d163895e968e3de85/xxhash-3.6.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:63275a8aba7865e44b1813d2177e0f5ea7eadad3dd063a21f7cf9afdc7054063", size = 212388 }, - { url = "https://files.pythonhosted.org/packages/f5/80/49f88d3afc724b4ac7fbd664c8452d6db51b49915be48c6982659e0e7942/xxhash-3.6.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cd01fa2aa00d8b017c97eb46b9a794fbdca53fc14f845f5a328c71254b0abb7", size = 445614 }, - { url = "https://files.pythonhosted.org/packages/ed/ba/603ce3961e339413543d8cd44f21f2c80e2a7c5cfe692a7b1f2cccf58f3c/xxhash-3.6.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0226aa89035b62b6a86d3c68df4d7c1f47a342b8683da2b60cedcddb46c4d95b", size = 194024 }, - { url = "https://files.pythonhosted.org/packages/78/d1/8e225ff7113bf81545cfdcd79eef124a7b7064a0bba53605ff39590b95c2/xxhash-3.6.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c6e193e9f56e4ca4923c61238cdaced324f0feac782544eb4c6d55ad5cc99ddd", size = 210541 }, - { url = "https://files.pythonhosted.org/packages/6f/58/0f89d149f0bad89def1a8dd38feb50ccdeb643d9797ec84707091d4cb494/xxhash-3.6.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:9176dcaddf4ca963d4deb93866d739a343c01c969231dbe21680e13a5d1a5bf0", size = 198305 }, - { url = "https://files.pythonhosted.org/packages/11/38/5eab81580703c4df93feb5f32ff8fa7fe1e2c51c1f183ee4e48d4bb9d3d7/xxhash-3.6.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:c1ce4009c97a752e682b897aa99aef84191077a9433eb237774689f14f8ec152", size = 210848 }, - { url = "https://files.pythonhosted.org/packages/5e/6b/953dc4b05c3ce678abca756416e4c130d2382f877a9c30a20d08ee6a77c0/xxhash-3.6.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:8cb2f4f679b01513b7adbb9b1b2f0f9cdc31b70007eaf9d59d0878809f385b11", size = 414142 }, - { url = "https://files.pythonhosted.org/packages/08/a9/238ec0d4e81a10eb5026d4a6972677cbc898ba6c8b9dbaec12ae001b1b35/xxhash-3.6.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:653a91d7c2ab54a92c19ccf43508b6a555440b9be1bc8be553376778be7f20b5", size = 191547 }, - { url = "https://files.pythonhosted.org/packages/f1/ee/3cf8589e06c2164ac77c3bf0aa127012801128f1feebf2a079272da5737c/xxhash-3.6.0-cp314-cp314-win32.whl", hash = "sha256:a756fe893389483ee8c394d06b5ab765d96e68fbbfe6fde7aa17e11f5720559f", size = 31214 }, - { url = "https://files.pythonhosted.org/packages/02/5d/a19552fbc6ad4cb54ff953c3908bbc095f4a921bc569433d791f755186f1/xxhash-3.6.0-cp314-cp314-win_amd64.whl", hash = "sha256:39be8e4e142550ef69629c9cd71b88c90e9a5db703fecbcf265546d9536ca4ad", size = 32290 }, - { url = "https://files.pythonhosted.org/packages/b1/11/dafa0643bc30442c887b55baf8e73353a344ee89c1901b5a5c54a6c17d39/xxhash-3.6.0-cp314-cp314-win_arm64.whl", hash = "sha256:25915e6000338999236f1eb68a02a32c3275ac338628a7eaa5a269c401995679", size = 28795 }, - { url = "https://files.pythonhosted.org/packages/2c/db/0e99732ed7f64182aef4a6fb145e1a295558deec2a746265dcdec12d191e/xxhash-3.6.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c5294f596a9017ca5a3e3f8884c00b91ab2ad2933cf288f4923c3fd4346cf3d4", size = 32955 }, - { url = "https://files.pythonhosted.org/packages/55/f4/2a7c3c68e564a099becfa44bb3d398810cc0ff6749b0d3cb8ccb93f23c14/xxhash-3.6.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1cf9dcc4ab9cff01dfbba78544297a3a01dafd60f3bde4e2bfd016cf7e4ddc67", size = 31072 }, - { url = "https://files.pythonhosted.org/packages/c6/d9/72a29cddc7250e8a5819dad5d466facb5dc4c802ce120645630149127e73/xxhash-3.6.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:01262da8798422d0685f7cef03b2bd3f4f46511b02830861df548d7def4402ad", size = 196579 }, - { url = "https://files.pythonhosted.org/packages/63/93/b21590e1e381040e2ca305a884d89e1c345b347404f7780f07f2cdd47ef4/xxhash-3.6.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:51a73fb7cb3a3ead9f7a8b583ffd9b8038e277cdb8cb87cf890e88b3456afa0b", size = 215854 }, - { url = "https://files.pythonhosted.org/packages/ce/b8/edab8a7d4fa14e924b29be877d54155dcbd8b80be85ea00d2be3413a9ed4/xxhash-3.6.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b9c6df83594f7df8f7f708ce5ebeacfc69f72c9fbaaababf6cf4758eaada0c9b", size = 214965 }, - { url = "https://files.pythonhosted.org/packages/27/67/dfa980ac7f0d509d54ea0d5a486d2bb4b80c3f1bb22b66e6a05d3efaf6c0/xxhash-3.6.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:627f0af069b0ea56f312fd5189001c24578868643203bca1abbc2c52d3a6f3ca", size = 448484 }, - { url = "https://files.pythonhosted.org/packages/8c/63/8ffc2cc97e811c0ca5d00ab36604b3ea6f4254f20b7bc658ca825ce6c954/xxhash-3.6.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aa912c62f842dfd013c5f21a642c9c10cd9f4c4e943e0af83618b4a404d9091a", size = 196162 }, - { url = "https://files.pythonhosted.org/packages/4b/77/07f0e7a3edd11a6097e990f6e5b815b6592459cb16dae990d967693e6ea9/xxhash-3.6.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:b465afd7909db30168ab62afe40b2fcf79eedc0b89a6c0ab3123515dc0df8b99", size = 213007 }, - { url = "https://files.pythonhosted.org/packages/ae/d8/bc5fa0d152837117eb0bef6f83f956c509332ce133c91c63ce07ee7c4873/xxhash-3.6.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:a881851cf38b0a70e7c4d3ce81fc7afd86fbc2a024f4cfb2a97cf49ce04b75d3", size = 200956 }, - { url = "https://files.pythonhosted.org/packages/26/a5/d749334130de9411783873e9b98ecc46688dad5db64ca6e04b02acc8b473/xxhash-3.6.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:9b3222c686a919a0f3253cfc12bb118b8b103506612253b5baeaac10d8027cf6", size = 213401 }, - { url = "https://files.pythonhosted.org/packages/89/72/abed959c956a4bfc72b58c0384bb7940663c678127538634d896b1195c10/xxhash-3.6.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:c5aa639bc113e9286137cec8fadc20e9cd732b2cc385c0b7fa673b84fc1f2a93", size = 417083 }, - { url = "https://files.pythonhosted.org/packages/0c/b3/62fd2b586283b7d7d665fb98e266decadf31f058f1cf6c478741f68af0cb/xxhash-3.6.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5c1343d49ac102799905e115aee590183c3921d475356cb24b4de29a4bc56518", size = 193913 }, - { url = "https://files.pythonhosted.org/packages/9a/9a/c19c42c5b3f5a4aad748a6d5b4f23df3bed7ee5445accc65a0fb3ff03953/xxhash-3.6.0-cp314-cp314t-win32.whl", hash = "sha256:5851f033c3030dd95c086b4a36a2683c2ff4a799b23af60977188b057e467119", size = 31586 }, - { url = "https://files.pythonhosted.org/packages/03/d6/4cc450345be9924fd5dc8c590ceda1db5b43a0a889587b0ae81a95511360/xxhash-3.6.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0444e7967dac37569052d2409b00a8860c2135cff05502df4da80267d384849f", size = 32526 }, - { url = "https://files.pythonhosted.org/packages/0f/c9/7243eb3f9eaabd1a88a5a5acadf06df2d83b100c62684b7425c6a11bcaa8/xxhash-3.6.0-cp314-cp314t-win_arm64.whl", hash = "sha256:bb79b1e63f6fd84ec778a4b1916dfe0a7c3fdb986c06addd5db3a0d413819d95", size = 28898 }, - { url = "https://files.pythonhosted.org/packages/93/1e/8aec23647a34a249f62e2398c42955acd9b4c6ed5cf08cbea94dc46f78d2/xxhash-3.6.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0f7b7e2ec26c1666ad5fc9dbfa426a6a3367ceaf79db5dd76264659d509d73b0", size = 30662 }, - { url = "https://files.pythonhosted.org/packages/b8/0b/b14510b38ba91caf43006209db846a696ceea6a847a0c9ba0a5b1adc53d6/xxhash-3.6.0-pp311-pypy311_pp73-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5dc1e14d14fa0f5789ec29a7062004b5933964bb9b02aae6622b8f530dc40296", size = 41056 }, - { url = "https://files.pythonhosted.org/packages/50/55/15a7b8a56590e66ccd374bbfa3f9ffc45b810886c8c3b614e3f90bd2367c/xxhash-3.6.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:881b47fc47e051b37d94d13e7455131054b56749b91b508b0907eb07900d1c13", size = 36251 }, - { url = "https://files.pythonhosted.org/packages/62/b2/5ac99a041a29e58e95f907876b04f7067a0242cb85b5f39e726153981503/xxhash-3.6.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c6dc31591899f5e5666f04cc2e529e69b4072827085c1ef15294d91a004bc1bd", size = 32481 }, - { url = "https://files.pythonhosted.org/packages/7b/d9/8d95e906764a386a3d3b596f3c68bb63687dfca806373509f51ce8eea81f/xxhash-3.6.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:15e0dac10eb9309508bfc41f7f9deaa7755c69e35af835db9cb10751adebc35d", size = 31565 }, -] - -[[package]] -name = "yarl" -version = "1.22.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "idna" }, - { name = "multidict" }, - { name = "propcache" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/57/63/0c6ebca57330cd313f6102b16dd57ffaf3ec4c83403dcb45dbd15c6f3ea1/yarl-1.22.0.tar.gz", hash = "sha256:bebf8557577d4401ba8bd9ff33906f1376c877aa78d1fe216ad01b4d6745af71", size = 187169 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4d/27/5ab13fc84c76a0250afd3d26d5936349a35be56ce5785447d6c423b26d92/yarl-1.22.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1ab72135b1f2db3fed3997d7e7dc1b80573c67138023852b6efb336a5eae6511", size = 141607 }, - { url = "https://files.pythonhosted.org/packages/6a/a1/d065d51d02dc02ce81501d476b9ed2229d9a990818332242a882d5d60340/yarl-1.22.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:669930400e375570189492dc8d8341301578e8493aec04aebc20d4717f899dd6", size = 94027 }, - { url = "https://files.pythonhosted.org/packages/c1/da/8da9f6a53f67b5106ffe902c6fa0164e10398d4e150d85838b82f424072a/yarl-1.22.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:792a2af6d58177ef7c19cbf0097aba92ca1b9cb3ffdd9c7470e156c8f9b5e028", size = 94963 }, - { url = "https://files.pythonhosted.org/packages/68/fe/2c1f674960c376e29cb0bec1249b117d11738db92a6ccc4a530b972648db/yarl-1.22.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3ea66b1c11c9150f1372f69afb6b8116f2dd7286f38e14ea71a44eee9ec51b9d", size = 368406 }, - { url = "https://files.pythonhosted.org/packages/95/26/812a540e1c3c6418fec60e9bbd38e871eaba9545e94fa5eff8f4a8e28e1e/yarl-1.22.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3e2daa88dc91870215961e96a039ec73e4937da13cf77ce17f9cad0c18df3503", size = 336581 }, - { url = "https://files.pythonhosted.org/packages/0b/f5/5777b19e26fdf98563985e481f8be3d8a39f8734147a6ebf459d0dab5a6b/yarl-1.22.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ba440ae430c00eee41509353628600212112cd5018d5def7e9b05ea7ac34eb65", size = 388924 }, - { url = "https://files.pythonhosted.org/packages/86/08/24bd2477bd59c0bbd994fe1d93b126e0472e4e3df5a96a277b0a55309e89/yarl-1.22.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e6438cc8f23a9c1478633d216b16104a586b9761db62bfacb6425bac0a36679e", size = 392890 }, - { url = "https://files.pythonhosted.org/packages/46/00/71b90ed48e895667ecfb1eaab27c1523ee2fa217433ed77a73b13205ca4b/yarl-1.22.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c52a6e78aef5cf47a98ef8e934755abf53953379b7d53e68b15ff4420e6683d", size = 365819 }, - { url = "https://files.pythonhosted.org/packages/30/2d/f715501cae832651d3282387c6a9236cd26bd00d0ff1e404b3dc52447884/yarl-1.22.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3b06bcadaac49c70f4c88af4ffcfbe3dc155aab3163e75777818092478bcbbe7", size = 363601 }, - { url = "https://files.pythonhosted.org/packages/f8/f9/a678c992d78e394e7126ee0b0e4e71bd2775e4334d00a9278c06a6cce96a/yarl-1.22.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:6944b2dc72c4d7f7052683487e3677456050ff77fcf5e6204e98caf785ad1967", size = 358072 }, - { url = "https://files.pythonhosted.org/packages/2c/d1/b49454411a60edb6fefdcad4f8e6dbba7d8019e3a508a1c5836cba6d0781/yarl-1.22.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d5372ca1df0f91a86b047d1277c2aaf1edb32d78bbcefffc81b40ffd18f027ed", size = 385311 }, - { url = "https://files.pythonhosted.org/packages/87/e5/40d7a94debb8448c7771a916d1861d6609dddf7958dc381117e7ba36d9e8/yarl-1.22.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:51af598701f5299012b8416486b40fceef8c26fc87dc6d7d1f6fc30609ea0aa6", size = 381094 }, - { url = "https://files.pythonhosted.org/packages/35/d8/611cc282502381ad855448643e1ad0538957fc82ae83dfe7762c14069e14/yarl-1.22.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b266bd01fedeffeeac01a79ae181719ff848a5a13ce10075adbefc8f1daee70e", size = 370944 }, - { url = "https://files.pythonhosted.org/packages/2d/df/fadd00fb1c90e1a5a8bd731fa3d3de2e165e5a3666a095b04e31b04d9cb6/yarl-1.22.0-cp311-cp311-win32.whl", hash = "sha256:a9b1ba5610a4e20f655258d5a1fdc7ebe3d837bb0e45b581398b99eb98b1f5ca", size = 81804 }, - { url = "https://files.pythonhosted.org/packages/b5/f7/149bb6f45f267cb5c074ac40c01c6b3ea6d8a620d34b337f6321928a1b4d/yarl-1.22.0-cp311-cp311-win_amd64.whl", hash = "sha256:078278b9b0b11568937d9509b589ee83ef98ed6d561dfe2020e24a9fd08eaa2b", size = 86858 }, - { url = "https://files.pythonhosted.org/packages/2b/13/88b78b93ad3f2f0b78e13bfaaa24d11cbc746e93fe76d8c06bf139615646/yarl-1.22.0-cp311-cp311-win_arm64.whl", hash = "sha256:b6a6f620cfe13ccec221fa312139135166e47ae169f8253f72a0abc0dae94376", size = 81637 }, - { url = "https://files.pythonhosted.org/packages/75/ff/46736024fee3429b80a165a732e38e5d5a238721e634ab41b040d49f8738/yarl-1.22.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e340382d1afa5d32b892b3ff062436d592ec3d692aeea3bef3a5cfe11bbf8c6f", size = 142000 }, - { url = "https://files.pythonhosted.org/packages/5a/9a/b312ed670df903145598914770eb12de1bac44599549b3360acc96878df8/yarl-1.22.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f1e09112a2c31ffe8d80be1b0988fa6a18c5d5cad92a9ffbb1c04c91bfe52ad2", size = 94338 }, - { url = "https://files.pythonhosted.org/packages/ba/f5/0601483296f09c3c65e303d60c070a5c19fcdbc72daa061e96170785bc7d/yarl-1.22.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:939fe60db294c786f6b7c2d2e121576628468f65453d86b0fe36cb52f987bd74", size = 94909 }, - { url = "https://files.pythonhosted.org/packages/60/41/9a1fe0b73dbcefce72e46cf149b0e0a67612d60bfc90fb59c2b2efdfbd86/yarl-1.22.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e1651bf8e0398574646744c1885a41198eba53dc8a9312b954073f845c90a8df", size = 372940 }, - { url = "https://files.pythonhosted.org/packages/17/7a/795cb6dfee561961c30b800f0ed616b923a2ec6258b5def2a00bf8231334/yarl-1.22.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b8a0588521a26bf92a57a1705b77b8b59044cdceccac7151bd8d229e66b8dedb", size = 345825 }, - { url = "https://files.pythonhosted.org/packages/d7/93/a58f4d596d2be2ae7bab1a5846c4d270b894958845753b2c606d666744d3/yarl-1.22.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:42188e6a615c1a75bcaa6e150c3fe8f3e8680471a6b10150c5f7e83f47cc34d2", size = 386705 }, - { url = "https://files.pythonhosted.org/packages/61/92/682279d0e099d0e14d7fd2e176bd04f48de1484f56546a3e1313cd6c8e7c/yarl-1.22.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f6d2cb59377d99718913ad9a151030d6f83ef420a2b8f521d94609ecc106ee82", size = 396518 }, - { url = "https://files.pythonhosted.org/packages/db/0f/0d52c98b8a885aeda831224b78f3be7ec2e1aa4a62091f9f9188c3c65b56/yarl-1.22.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50678a3b71c751d58d7908edc96d332af328839eea883bb554a43f539101277a", size = 377267 }, - { url = "https://files.pythonhosted.org/packages/22/42/d2685e35908cbeaa6532c1fc73e89e7f2efb5d8a7df3959ea8e37177c5a3/yarl-1.22.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1e8fbaa7cec507aa24ea27a01456e8dd4b6fab829059b69844bd348f2d467124", size = 365797 }, - { url = "https://files.pythonhosted.org/packages/a2/83/cf8c7bcc6355631762f7d8bdab920ad09b82efa6b722999dfb05afa6cfac/yarl-1.22.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:433885ab5431bc3d3d4f2f9bd15bfa1614c522b0f1405d62c4f926ccd69d04fa", size = 365535 }, - { url = "https://files.pythonhosted.org/packages/25/e1/5302ff9b28f0c59cac913b91fe3f16c59a033887e57ce9ca5d41a3a94737/yarl-1.22.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b790b39c7e9a4192dc2e201a282109ed2985a1ddbd5ac08dc56d0e121400a8f7", size = 382324 }, - { url = "https://files.pythonhosted.org/packages/bf/cd/4617eb60f032f19ae3a688dc990d8f0d89ee0ea378b61cac81ede3e52fae/yarl-1.22.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:31f0b53913220599446872d757257be5898019c85e7971599065bc55065dc99d", size = 383803 }, - { url = "https://files.pythonhosted.org/packages/59/65/afc6e62bb506a319ea67b694551dab4a7e6fb7bf604e9bd9f3e11d575fec/yarl-1.22.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a49370e8f711daec68d09b821a34e1167792ee2d24d405cbc2387be4f158b520", size = 374220 }, - { url = "https://files.pythonhosted.org/packages/e7/3d/68bf18d50dc674b942daec86a9ba922d3113d8399b0e52b9897530442da2/yarl-1.22.0-cp312-cp312-win32.whl", hash = "sha256:70dfd4f241c04bd9239d53b17f11e6ab672b9f1420364af63e8531198e3f5fe8", size = 81589 }, - { url = "https://files.pythonhosted.org/packages/c8/9a/6ad1a9b37c2f72874f93e691b2e7ecb6137fb2b899983125db4204e47575/yarl-1.22.0-cp312-cp312-win_amd64.whl", hash = "sha256:8884d8b332a5e9b88e23f60bb166890009429391864c685e17bd73a9eda9105c", size = 87213 }, - { url = "https://files.pythonhosted.org/packages/44/c5/c21b562d1680a77634d748e30c653c3ca918beb35555cff24986fff54598/yarl-1.22.0-cp312-cp312-win_arm64.whl", hash = "sha256:ea70f61a47f3cc93bdf8b2f368ed359ef02a01ca6393916bc8ff877427181e74", size = 81330 }, - { url = "https://files.pythonhosted.org/packages/ea/f3/d67de7260456ee105dc1d162d43a019ecad6b91e2f51809d6cddaa56690e/yarl-1.22.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8dee9c25c74997f6a750cd317b8ca63545169c098faee42c84aa5e506c819b53", size = 139980 }, - { url = "https://files.pythonhosted.org/packages/01/88/04d98af0b47e0ef42597b9b28863b9060bb515524da0a65d5f4db160b2d5/yarl-1.22.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:01e73b85a5434f89fc4fe27dcda2aff08ddf35e4d47bbbea3bdcd25321af538a", size = 93424 }, - { url = "https://files.pythonhosted.org/packages/18/91/3274b215fd8442a03975ce6bee5fe6aa57a8326b29b9d3d56234a1dca244/yarl-1.22.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:22965c2af250d20c873cdbee8ff958fb809940aeb2e74ba5f20aaf6b7ac8c70c", size = 93821 }, - { url = "https://files.pythonhosted.org/packages/61/3a/caf4e25036db0f2da4ca22a353dfeb3c9d3c95d2761ebe9b14df8fc16eb0/yarl-1.22.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4f15793aa49793ec8d1c708ab7f9eded1aa72edc5174cae703651555ed1b601", size = 373243 }, - { url = "https://files.pythonhosted.org/packages/6e/9e/51a77ac7516e8e7803b06e01f74e78649c24ee1021eca3d6a739cb6ea49c/yarl-1.22.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5542339dcf2747135c5c85f68680353d5cb9ffd741c0f2e8d832d054d41f35a", size = 342361 }, - { url = "https://files.pythonhosted.org/packages/d4/f8/33b92454789dde8407f156c00303e9a891f1f51a0330b0fad7c909f87692/yarl-1.22.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5c401e05ad47a75869c3ab3e35137f8468b846770587e70d71e11de797d113df", size = 387036 }, - { url = "https://files.pythonhosted.org/packages/d9/9a/c5db84ea024f76838220280f732970aa4ee154015d7f5c1bfb60a267af6f/yarl-1.22.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:243dda95d901c733f5b59214d28b0120893d91777cb8aa043e6ef059d3cddfe2", size = 397671 }, - { url = "https://files.pythonhosted.org/packages/11/c9/cd8538dc2e7727095e0c1d867bad1e40c98f37763e6d995c1939f5fdc7b1/yarl-1.22.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bec03d0d388060058f5d291a813f21c011041938a441c593374da6077fe21b1b", size = 377059 }, - { url = "https://files.pythonhosted.org/packages/a1/b9/ab437b261702ced75122ed78a876a6dec0a1b0f5e17a4ac7a9a2482d8abe/yarl-1.22.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b0748275abb8c1e1e09301ee3cf90c8a99678a4e92e4373705f2a2570d581273", size = 365356 }, - { url = "https://files.pythonhosted.org/packages/b2/9d/8e1ae6d1d008a9567877b08f0ce4077a29974c04c062dabdb923ed98e6fe/yarl-1.22.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:47fdb18187e2a4e18fda2c25c05d8251a9e4a521edaed757fef033e7d8498d9a", size = 361331 }, - { url = "https://files.pythonhosted.org/packages/ca/5a/09b7be3905962f145b73beb468cdd53db8aa171cf18c80400a54c5b82846/yarl-1.22.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c7044802eec4524fde550afc28edda0dd5784c4c45f0be151a2d3ba017daca7d", size = 382590 }, - { url = "https://files.pythonhosted.org/packages/aa/7f/59ec509abf90eda5048b0bc3e2d7b5099dffdb3e6b127019895ab9d5ef44/yarl-1.22.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:139718f35149ff544caba20fce6e8a2f71f1e39b92c700d8438a0b1d2a631a02", size = 385316 }, - { url = "https://files.pythonhosted.org/packages/e5/84/891158426bc8036bfdfd862fabd0e0fa25df4176ec793e447f4b85cf1be4/yarl-1.22.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e1b51bebd221006d3d2f95fbe124b22b247136647ae5dcc8c7acafba66e5ee67", size = 374431 }, - { url = "https://files.pythonhosted.org/packages/bb/49/03da1580665baa8bef5e8ed34c6df2c2aca0a2f28bf397ed238cc1bbc6f2/yarl-1.22.0-cp313-cp313-win32.whl", hash = "sha256:d3e32536234a95f513bd374e93d717cf6b2231a791758de6c509e3653f234c95", size = 81555 }, - { url = "https://files.pythonhosted.org/packages/9a/ee/450914ae11b419eadd067c6183ae08381cfdfcb9798b90b2b713bbebddda/yarl-1.22.0-cp313-cp313-win_amd64.whl", hash = "sha256:47743b82b76d89a1d20b83e60d5c20314cbd5ba2befc9cda8f28300c4a08ed4d", size = 86965 }, - { url = "https://files.pythonhosted.org/packages/98/4d/264a01eae03b6cf629ad69bae94e3b0e5344741e929073678e84bf7a3e3b/yarl-1.22.0-cp313-cp313-win_arm64.whl", hash = "sha256:5d0fcda9608875f7d052eff120c7a5da474a6796fe4d83e152e0e4d42f6d1a9b", size = 81205 }, - { url = "https://files.pythonhosted.org/packages/88/fc/6908f062a2f77b5f9f6d69cecb1747260831ff206adcbc5b510aff88df91/yarl-1.22.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:719ae08b6972befcba4310e49edb1161a88cdd331e3a694b84466bd938a6ab10", size = 146209 }, - { url = "https://files.pythonhosted.org/packages/65/47/76594ae8eab26210b4867be6f49129861ad33da1f1ebdf7051e98492bf62/yarl-1.22.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:47d8a5c446df1c4db9d21b49619ffdba90e77c89ec6e283f453856c74b50b9e3", size = 95966 }, - { url = "https://files.pythonhosted.org/packages/ab/ce/05e9828a49271ba6b5b038b15b3934e996980dd78abdfeb52a04cfb9467e/yarl-1.22.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cfebc0ac8333520d2d0423cbbe43ae43c8838862ddb898f5ca68565e395516e9", size = 97312 }, - { url = "https://files.pythonhosted.org/packages/d1/c5/7dffad5e4f2265b29c9d7ec869c369e4223166e4f9206fc2243ee9eea727/yarl-1.22.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4398557cbf484207df000309235979c79c4356518fd5c99158c7d38203c4da4f", size = 361967 }, - { url = "https://files.pythonhosted.org/packages/50/b2/375b933c93a54bff7fc041e1a6ad2c0f6f733ffb0c6e642ce56ee3b39970/yarl-1.22.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2ca6fd72a8cd803be290d42f2dec5cdcd5299eeb93c2d929bf060ad9efaf5de0", size = 323949 }, - { url = "https://files.pythonhosted.org/packages/66/50/bfc2a29a1d78644c5a7220ce2f304f38248dc94124a326794e677634b6cf/yarl-1.22.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca1f59c4e1ab6e72f0a23c13fca5430f889634166be85dbf1013683e49e3278e", size = 361818 }, - { url = "https://files.pythonhosted.org/packages/46/96/f3941a46af7d5d0f0498f86d71275696800ddcdd20426298e572b19b91ff/yarl-1.22.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c5010a52015e7c70f86eb967db0f37f3c8bd503a695a49f8d45700144667708", size = 372626 }, - { url = "https://files.pythonhosted.org/packages/c1/42/8b27c83bb875cd89448e42cd627e0fb971fa1675c9ec546393d18826cb50/yarl-1.22.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d7672ecf7557476642c88497c2f8d8542f8e36596e928e9bcba0e42e1e7d71f", size = 341129 }, - { url = "https://files.pythonhosted.org/packages/49/36/99ca3122201b382a3cf7cc937b95235b0ac944f7e9f2d5331d50821ed352/yarl-1.22.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3b7c88eeef021579d600e50363e0b6ee4f7f6f728cd3486b9d0f3ee7b946398d", size = 346776 }, - { url = "https://files.pythonhosted.org/packages/85/b4/47328bf996acd01a4c16ef9dcd2f59c969f495073616586f78cd5f2efb99/yarl-1.22.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:f4afb5c34f2c6fecdcc182dfcfc6af6cccf1aa923eed4d6a12e9d96904e1a0d8", size = 334879 }, - { url = "https://files.pythonhosted.org/packages/c2/ad/b77d7b3f14a4283bffb8e92c6026496f6de49751c2f97d4352242bba3990/yarl-1.22.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:59c189e3e99a59cf8d83cbb31d4db02d66cda5a1a4374e8a012b51255341abf5", size = 350996 }, - { url = "https://files.pythonhosted.org/packages/81/c8/06e1d69295792ba54d556f06686cbd6a7ce39c22307100e3fb4a2c0b0a1d/yarl-1.22.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:5a3bf7f62a289fa90f1990422dc8dff5a458469ea71d1624585ec3a4c8d6960f", size = 356047 }, - { url = "https://files.pythonhosted.org/packages/4b/b8/4c0e9e9f597074b208d18cef227d83aac36184bfbc6eab204ea55783dbc5/yarl-1.22.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:de6b9a04c606978fdfe72666fa216ffcf2d1a9f6a381058d4378f8d7b1e5de62", size = 342947 }, - { url = "https://files.pythonhosted.org/packages/e0/e5/11f140a58bf4c6ad7aca69a892bff0ee638c31bea4206748fc0df4ebcb3a/yarl-1.22.0-cp313-cp313t-win32.whl", hash = "sha256:1834bb90991cc2999f10f97f5f01317f99b143284766d197e43cd5b45eb18d03", size = 86943 }, - { url = "https://files.pythonhosted.org/packages/31/74/8b74bae38ed7fe6793d0c15a0c8207bbb819cf287788459e5ed230996cdd/yarl-1.22.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ff86011bd159a9d2dfc89c34cfd8aff12875980e3bd6a39ff097887520e60249", size = 93715 }, - { url = "https://files.pythonhosted.org/packages/69/66/991858aa4b5892d57aef7ee1ba6b4d01ec3b7eb3060795d34090a3ca3278/yarl-1.22.0-cp313-cp313t-win_arm64.whl", hash = "sha256:7861058d0582b847bc4e3a4a4c46828a410bca738673f35a29ba3ca5db0b473b", size = 83857 }, - { url = "https://files.pythonhosted.org/packages/46/b3/e20ef504049f1a1c54a814b4b9bed96d1ac0e0610c3b4da178f87209db05/yarl-1.22.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:34b36c2c57124530884d89d50ed2c1478697ad7473efd59cfd479945c95650e4", size = 140520 }, - { url = "https://files.pythonhosted.org/packages/e4/04/3532d990fdbab02e5ede063676b5c4260e7f3abea2151099c2aa745acc4c/yarl-1.22.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:0dd9a702591ca2e543631c2a017e4a547e38a5c0f29eece37d9097e04a7ac683", size = 93504 }, - { url = "https://files.pythonhosted.org/packages/11/63/ff458113c5c2dac9a9719ac68ee7c947cb621432bcf28c9972b1c0e83938/yarl-1.22.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:594fcab1032e2d2cc3321bb2e51271e7cd2b516c7d9aee780ece81b07ff8244b", size = 94282 }, - { url = "https://files.pythonhosted.org/packages/a7/bc/315a56aca762d44a6aaaf7ad253f04d996cb6b27bad34410f82d76ea8038/yarl-1.22.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3d7a87a78d46a2e3d5b72587ac14b4c16952dd0887dbb051451eceac774411e", size = 372080 }, - { url = "https://files.pythonhosted.org/packages/3f/3f/08e9b826ec2e099ea6e7c69a61272f4f6da62cb5b1b63590bb80ca2e4a40/yarl-1.22.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:852863707010316c973162e703bddabec35e8757e67fcb8ad58829de1ebc8590", size = 338696 }, - { url = "https://files.pythonhosted.org/packages/e3/9f/90360108e3b32bd76789088e99538febfea24a102380ae73827f62073543/yarl-1.22.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:131a085a53bfe839a477c0845acf21efc77457ba2bcf5899618136d64f3303a2", size = 387121 }, - { url = "https://files.pythonhosted.org/packages/98/92/ab8d4657bd5b46a38094cfaea498f18bb70ce6b63508fd7e909bd1f93066/yarl-1.22.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:078a8aefd263f4d4f923a9677b942b445a2be970ca24548a8102689a3a8ab8da", size = 394080 }, - { url = "https://files.pythonhosted.org/packages/f5/e7/d8c5a7752fef68205296201f8ec2bf718f5c805a7a7e9880576c67600658/yarl-1.22.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bca03b91c323036913993ff5c738d0842fc9c60c4648e5c8d98331526df89784", size = 372661 }, - { url = "https://files.pythonhosted.org/packages/b6/2e/f4d26183c8db0bb82d491b072f3127fb8c381a6206a3a56332714b79b751/yarl-1.22.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:68986a61557d37bb90d3051a45b91fa3d5c516d177dfc6dd6f2f436a07ff2b6b", size = 364645 }, - { url = "https://files.pythonhosted.org/packages/80/7c/428e5812e6b87cd00ee8e898328a62c95825bf37c7fa87f0b6bb2ad31304/yarl-1.22.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:4792b262d585ff0dff6bcb787f8492e40698443ec982a3568c2096433660c694", size = 355361 }, - { url = "https://files.pythonhosted.org/packages/ec/2a/249405fd26776f8b13c067378ef4d7dd49c9098d1b6457cdd152a99e96a9/yarl-1.22.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ebd4549b108d732dba1d4ace67614b9545b21ece30937a63a65dd34efa19732d", size = 381451 }, - { url = "https://files.pythonhosted.org/packages/67/a8/fb6b1adbe98cf1e2dd9fad71003d3a63a1bc22459c6e15f5714eb9323b93/yarl-1.22.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f87ac53513d22240c7d59203f25cc3beac1e574c6cd681bbfd321987b69f95fd", size = 383814 }, - { url = "https://files.pythonhosted.org/packages/d9/f9/3aa2c0e480fb73e872ae2814c43bc1e734740bb0d54e8cb2a95925f98131/yarl-1.22.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:22b029f2881599e2f1b06f8f1db2ee63bd309e2293ba2d566e008ba12778b8da", size = 370799 }, - { url = "https://files.pythonhosted.org/packages/50/3c/af9dba3b8b5eeb302f36f16f92791f3ea62e3f47763406abf6d5a4a3333b/yarl-1.22.0-cp314-cp314-win32.whl", hash = "sha256:6a635ea45ba4ea8238463b4f7d0e721bad669f80878b7bfd1f89266e2ae63da2", size = 82990 }, - { url = "https://files.pythonhosted.org/packages/ac/30/ac3a0c5bdc1d6efd1b41fa24d4897a4329b3b1e98de9449679dd327af4f0/yarl-1.22.0-cp314-cp314-win_amd64.whl", hash = "sha256:0d6e6885777af0f110b0e5d7e5dda8b704efed3894da26220b7f3d887b839a79", size = 88292 }, - { url = "https://files.pythonhosted.org/packages/df/0a/227ab4ff5b998a1b7410abc7b46c9b7a26b0ca9e86c34ba4b8d8bc7c63d5/yarl-1.22.0-cp314-cp314-win_arm64.whl", hash = "sha256:8218f4e98d3c10d683584cb40f0424f4b9fd6e95610232dd75e13743b070ee33", size = 82888 }, - { url = "https://files.pythonhosted.org/packages/06/5e/a15eb13db90abd87dfbefb9760c0f3f257ac42a5cac7e75dbc23bed97a9f/yarl-1.22.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:45c2842ff0e0d1b35a6bf1cd6c690939dacb617a70827f715232b2e0494d55d1", size = 146223 }, - { url = "https://files.pythonhosted.org/packages/18/82/9665c61910d4d84f41a5bf6837597c89e665fa88aa4941080704645932a9/yarl-1.22.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:d947071e6ebcf2e2bee8fce76e10faca8f7a14808ca36a910263acaacef08eca", size = 95981 }, - { url = "https://files.pythonhosted.org/packages/5d/9a/2f65743589809af4d0a6d3aa749343c4b5f4c380cc24a8e94a3c6625a808/yarl-1.22.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:334b8721303e61b00019474cc103bdac3d7b1f65e91f0bfedeec2d56dfe74b53", size = 97303 }, - { url = "https://files.pythonhosted.org/packages/b0/ab/5b13d3e157505c43c3b43b5a776cbf7b24a02bc4cccc40314771197e3508/yarl-1.22.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e7ce67c34138a058fd092f67d07a72b8e31ff0c9236e751957465a24b28910c", size = 361820 }, - { url = "https://files.pythonhosted.org/packages/fb/76/242a5ef4677615cf95330cfc1b4610e78184400699bdda0acb897ef5e49a/yarl-1.22.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d77e1b2c6d04711478cb1c4ab90db07f1609ccf06a287d5607fcd90dc9863acf", size = 323203 }, - { url = "https://files.pythonhosted.org/packages/8c/96/475509110d3f0153b43d06164cf4195c64d16999e0c7e2d8a099adcd6907/yarl-1.22.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4647674b6150d2cae088fc07de2738a84b8bcedebef29802cf0b0a82ab6face", size = 363173 }, - { url = "https://files.pythonhosted.org/packages/c9/66/59db471aecfbd559a1fd48aedd954435558cd98c7d0da8b03cc6c140a32c/yarl-1.22.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efb07073be061c8f79d03d04139a80ba33cbd390ca8f0297aae9cce6411e4c6b", size = 373562 }, - { url = "https://files.pythonhosted.org/packages/03/1f/c5d94abc91557384719da10ff166b916107c1b45e4d0423a88457071dd88/yarl-1.22.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e51ac5435758ba97ad69617e13233da53908beccc6cfcd6c34bbed8dcbede486", size = 339828 }, - { url = "https://files.pythonhosted.org/packages/5f/97/aa6a143d3afba17b6465733681c70cf175af89f76ec8d9286e08437a7454/yarl-1.22.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:33e32a0dd0c8205efa8e83d04fc9f19313772b78522d1bdc7d9aed706bfd6138", size = 347551 }, - { url = "https://files.pythonhosted.org/packages/43/3c/45a2b6d80195959239a7b2a8810506d4eea5487dce61c2a3393e7fc3c52e/yarl-1.22.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:bf4a21e58b9cde0e401e683ebd00f6ed30a06d14e93f7c8fd059f8b6e8f87b6a", size = 334512 }, - { url = "https://files.pythonhosted.org/packages/86/a0/c2ab48d74599c7c84cb104ebd799c5813de252bea0f360ffc29d270c2caa/yarl-1.22.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:e4b582bab49ac33c8deb97e058cd67c2c50dac0dd134874106d9c774fd272529", size = 352400 }, - { url = "https://files.pythonhosted.org/packages/32/75/f8919b2eafc929567d3d8411f72bdb1a2109c01caaab4ebfa5f8ffadc15b/yarl-1.22.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0b5bcc1a9c4839e7e30b7b30dd47fe5e7e44fb7054ec29b5bb8d526aa1041093", size = 357140 }, - { url = "https://files.pythonhosted.org/packages/cf/72/6a85bba382f22cf78add705d8c3731748397d986e197e53ecc7835e76de7/yarl-1.22.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c0232bce2170103ec23c454e54a57008a9a72b5d1c3105dc2496750da8cfa47c", size = 341473 }, - { url = "https://files.pythonhosted.org/packages/35/18/55e6011f7c044dc80b98893060773cefcfdbf60dfefb8cb2f58b9bacbd83/yarl-1.22.0-cp314-cp314t-win32.whl", hash = "sha256:8009b3173bcd637be650922ac455946197d858b3630b6d8787aa9e5c4564533e", size = 89056 }, - { url = "https://files.pythonhosted.org/packages/f9/86/0f0dccb6e59a9e7f122c5afd43568b1d31b8ab7dda5f1b01fb5c7025c9a9/yarl-1.22.0-cp314-cp314t-win_amd64.whl", hash = "sha256:9fb17ea16e972c63d25d4a97f016d235c78dd2344820eb35bc034bc32012ee27", size = 96292 }, - { url = "https://files.pythonhosted.org/packages/48/b7/503c98092fb3b344a179579f55814b613c1fbb1c23b3ec14a7b008a66a6e/yarl-1.22.0-cp314-cp314t-win_arm64.whl", hash = "sha256:9f6d73c1436b934e3f01df1e1b21ff765cd1d28c77dfb9ace207f746d4610ee1", size = 85171 }, - { url = "https://files.pythonhosted.org/packages/73/ae/b48f95715333080afb75a4504487cbe142cae1268afc482d06692d605ae6/yarl-1.22.0-py3-none-any.whl", hash = "sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff", size = 46814 }, + { url = "https://files.pythonhosted.org/packages/2a/83/c3ca27c363d104980f1c9cee1101cc8ba724ac8c28a033ede6aab89585b1/zstandard-0.25.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:933b65d7680ea337180733cf9e87293cc5500cc0eb3fc8769f4d3c88d724ec5c", size = 795254 }, + { url = "https://files.pythonhosted.org/packages/ac/4d/e66465c5411a7cf4866aeadc7d108081d8ceba9bc7abe6b14aa21c671ec3/zstandard-0.25.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a3f79487c687b1fc69f19e487cd949bf3aae653d181dfb5fde3bf6d18894706f", size = 640559 }, + { url = "https://files.pythonhosted.org/packages/12/56/354fe655905f290d3b147b33fe946b0f27e791e4b50a5f004c802cb3eb7b/zstandard-0.25.0-cp311-cp311-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:0bbc9a0c65ce0eea3c34a691e3c4b6889f5f3909ba4822ab385fab9057099431", size = 5348020 }, + { url = "https://files.pythonhosted.org/packages/3b/13/2b7ed68bd85e69a2069bcc72141d378f22cae5a0f3b353a2c8f50ef30c1b/zstandard-0.25.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:01582723b3ccd6939ab7b3a78622c573799d5d8737b534b86d0e06ac18dbde4a", size = 5058126 }, + { url = "https://files.pythonhosted.org/packages/c9/dd/fdaf0674f4b10d92cb120ccff58bbb6626bf8368f00ebfd2a41ba4a0dc99/zstandard-0.25.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:5f1ad7bf88535edcf30038f6919abe087f606f62c00a87d7e33e7fc57cb69fcc", size = 5405390 }, + { url = "https://files.pythonhosted.org/packages/0f/67/354d1555575bc2490435f90d67ca4dd65238ff2f119f30f72d5cde09c2ad/zstandard-0.25.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:06acb75eebeedb77b69048031282737717a63e71e4ae3f77cc0c3b9508320df6", size = 5452914 }, + { url = "https://files.pythonhosted.org/packages/bb/1f/e9cfd801a3f9190bf3e759c422bbfd2247db9d7f3d54a56ecde70137791a/zstandard-0.25.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9300d02ea7c6506f00e627e287e0492a5eb0371ec1670ae852fefffa6164b072", size = 5559635 }, + { url = "https://files.pythonhosted.org/packages/21/88/5ba550f797ca953a52d708c8e4f380959e7e3280af029e38fbf47b55916e/zstandard-0.25.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bfd06b1c5584b657a2892a6014c2f4c20e0db0208c159148fa78c65f7e0b0277", size = 5048277 }, + { url = "https://files.pythonhosted.org/packages/46/c0/ca3e533b4fa03112facbe7fbe7779cb1ebec215688e5df576fe5429172e0/zstandard-0.25.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f373da2c1757bb7f1acaf09369cdc1d51d84131e50d5fa9863982fd626466313", size = 5574377 }, + { url = "https://files.pythonhosted.org/packages/12/9b/3fb626390113f272abd0799fd677ea33d5fc3ec185e62e6be534493c4b60/zstandard-0.25.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6c0e5a65158a7946e7a7affa6418878ef97ab66636f13353b8502d7ea03c8097", size = 4961493 }, + { url = "https://files.pythonhosted.org/packages/cb/d3/23094a6b6a4b1343b27ae68249daa17ae0651fcfec9ed4de09d14b940285/zstandard-0.25.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c8e167d5adf59476fa3e37bee730890e389410c354771a62e3c076c86f9f7778", size = 5269018 }, + { url = "https://files.pythonhosted.org/packages/8c/a7/bb5a0c1c0f3f4b5e9d5b55198e39de91e04ba7c205cc46fcb0f95f0383c1/zstandard-0.25.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:98750a309eb2f020da61e727de7d7ba3c57c97cf6213f6f6277bb7fb42a8e065", size = 5443672 }, + { url = "https://files.pythonhosted.org/packages/27/22/503347aa08d073993f25109c36c8d9f029c7d5949198050962cb568dfa5e/zstandard-0.25.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:22a086cff1b6ceca18a8dd6096ec631e430e93a8e70a9ca5efa7561a00f826fa", size = 5822753 }, + { url = "https://files.pythonhosted.org/packages/e2/be/94267dc6ee64f0f8ba2b2ae7c7a2df934a816baaa7291db9e1aa77394c3c/zstandard-0.25.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:72d35d7aa0bba323965da807a462b0966c91608ef3a48ba761678cb20ce5d8b7", size = 5366047 }, + { url = "https://files.pythonhosted.org/packages/7b/a3/732893eab0a3a7aecff8b99052fecf9f605cf0fb5fb6d0290e36beee47a4/zstandard-0.25.0-cp311-cp311-win32.whl", hash = "sha256:f5aeea11ded7320a84dcdd62a3d95b5186834224a9e55b92ccae35d21a8b63d4", size = 436484 }, + { url = "https://files.pythonhosted.org/packages/43/a3/c6155f5c1cce691cb80dfd38627046e50af3ee9ddc5d0b45b9b063bfb8c9/zstandard-0.25.0-cp311-cp311-win_amd64.whl", hash = "sha256:daab68faadb847063d0c56f361a289c4f268706b598afbf9ad113cbe5c38b6b2", size = 506183 }, + { url = "https://files.pythonhosted.org/packages/8c/3e/8945ab86a0820cc0e0cdbf38086a92868a9172020fdab8a03ac19662b0e5/zstandard-0.25.0-cp311-cp311-win_arm64.whl", hash = "sha256:22a06c5df3751bb7dc67406f5374734ccee8ed37fc5981bf1ad7041831fa1137", size = 462533 }, + { url = "https://files.pythonhosted.org/packages/82/fc/f26eb6ef91ae723a03e16eddb198abcfce2bc5a42e224d44cc8b6765e57e/zstandard-0.25.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7b3c3a3ab9daa3eed242d6ecceead93aebbb8f5f84318d82cee643e019c4b73b", size = 795738 }, + { url = "https://files.pythonhosted.org/packages/aa/1c/d920d64b22f8dd028a8b90e2d756e431a5d86194caa78e3819c7bf53b4b3/zstandard-0.25.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:913cbd31a400febff93b564a23e17c3ed2d56c064006f54efec210d586171c00", size = 640436 }, + { url = "https://files.pythonhosted.org/packages/53/6c/288c3f0bd9fcfe9ca41e2c2fbfd17b2097f6af57b62a81161941f09afa76/zstandard-0.25.0-cp312-cp312-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:011d388c76b11a0c165374ce660ce2c8efa8e5d87f34996aa80f9c0816698b64", size = 5343019 }, + { url = "https://files.pythonhosted.org/packages/1e/15/efef5a2f204a64bdb5571e6161d49f7ef0fffdbca953a615efbec045f60f/zstandard-0.25.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6dffecc361d079bb48d7caef5d673c88c8988d3d33fb74ab95b7ee6da42652ea", size = 5063012 }, + { url = "https://files.pythonhosted.org/packages/b7/37/a6ce629ffdb43959e92e87ebdaeebb5ac81c944b6a75c9c47e300f85abdf/zstandard-0.25.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:7149623bba7fdf7e7f24312953bcf73cae103db8cae49f8154dd1eadc8a29ecb", size = 5394148 }, + { url = "https://files.pythonhosted.org/packages/e3/79/2bf870b3abeb5c070fe2d670a5a8d1057a8270f125ef7676d29ea900f496/zstandard-0.25.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:6a573a35693e03cf1d67799fd01b50ff578515a8aeadd4595d2a7fa9f3ec002a", size = 5451652 }, + { url = "https://files.pythonhosted.org/packages/53/60/7be26e610767316c028a2cbedb9a3beabdbe33e2182c373f71a1c0b88f36/zstandard-0.25.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5a56ba0db2d244117ed744dfa8f6f5b366e14148e00de44723413b2f3938a902", size = 5546993 }, + { url = "https://files.pythonhosted.org/packages/85/c7/3483ad9ff0662623f3648479b0380d2de5510abf00990468c286c6b04017/zstandard-0.25.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:10ef2a79ab8e2974e2075fb984e5b9806c64134810fac21576f0668e7ea19f8f", size = 5046806 }, + { url = "https://files.pythonhosted.org/packages/08/b3/206883dd25b8d1591a1caa44b54c2aad84badccf2f1de9e2d60a446f9a25/zstandard-0.25.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aaf21ba8fb76d102b696781bddaa0954b782536446083ae3fdaa6f16b25a1c4b", size = 5576659 }, + { url = "https://files.pythonhosted.org/packages/9d/31/76c0779101453e6c117b0ff22565865c54f48f8bd807df2b00c2c404b8e0/zstandard-0.25.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1869da9571d5e94a85a5e8d57e4e8807b175c9e4a6294e3b66fa4efb074d90f6", size = 4953933 }, + { url = "https://files.pythonhosted.org/packages/18/e1/97680c664a1bf9a247a280a053d98e251424af51f1b196c6d52f117c9720/zstandard-0.25.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:809c5bcb2c67cd0ed81e9229d227d4ca28f82d0f778fc5fea624a9def3963f91", size = 5268008 }, + { url = "https://files.pythonhosted.org/packages/1e/73/316e4010de585ac798e154e88fd81bb16afc5c5cb1a72eeb16dd37e8024a/zstandard-0.25.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f27662e4f7dbf9f9c12391cb37b4c4c3cb90ffbd3b1fb9284dadbbb8935fa708", size = 5433517 }, + { url = "https://files.pythonhosted.org/packages/5b/60/dd0f8cfa8129c5a0ce3ea6b7f70be5b33d2618013a161e1ff26c2b39787c/zstandard-0.25.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:99c0c846e6e61718715a3c9437ccc625de26593fea60189567f0118dc9db7512", size = 5814292 }, + { url = "https://files.pythonhosted.org/packages/fc/5f/75aafd4b9d11b5407b641b8e41a57864097663699f23e9ad4dbb91dc6bfe/zstandard-0.25.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:474d2596a2dbc241a556e965fb76002c1ce655445e4e3bf38e5477d413165ffa", size = 5360237 }, + { url = "https://files.pythonhosted.org/packages/ff/8d/0309daffea4fcac7981021dbf21cdb2e3427a9e76bafbcdbdf5392ff99a4/zstandard-0.25.0-cp312-cp312-win32.whl", hash = "sha256:23ebc8f17a03133b4426bcc04aabd68f8236eb78c3760f12783385171b0fd8bd", size = 436922 }, + { url = "https://files.pythonhosted.org/packages/79/3b/fa54d9015f945330510cb5d0b0501e8253c127cca7ebe8ba46a965df18c5/zstandard-0.25.0-cp312-cp312-win_amd64.whl", hash = "sha256:ffef5a74088f1e09947aecf91011136665152e0b4b359c42be3373897fb39b01", size = 506276 }, + { url = "https://files.pythonhosted.org/packages/ea/6b/8b51697e5319b1f9ac71087b0af9a40d8a6288ff8025c36486e0c12abcc4/zstandard-0.25.0-cp312-cp312-win_arm64.whl", hash = "sha256:181eb40e0b6a29b3cd2849f825e0fa34397f649170673d385f3598ae17cca2e9", size = 462679 }, + { url = "https://files.pythonhosted.org/packages/35/0b/8df9c4ad06af91d39e94fa96cc010a24ac4ef1378d3efab9223cc8593d40/zstandard-0.25.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec996f12524f88e151c339688c3897194821d7f03081ab35d31d1e12ec975e94", size = 795735 }, + { url = "https://files.pythonhosted.org/packages/3f/06/9ae96a3e5dcfd119377ba33d4c42a7d89da1efabd5cb3e366b156c45ff4d/zstandard-0.25.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a1a4ae2dec3993a32247995bdfe367fc3266da832d82f8438c8570f989753de1", size = 640440 }, + { url = "https://files.pythonhosted.org/packages/d9/14/933d27204c2bd404229c69f445862454dcc101cd69ef8c6068f15aaec12c/zstandard-0.25.0-cp313-cp313-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:e96594a5537722fdfb79951672a2a63aec5ebfb823e7560586f7484819f2a08f", size = 5343070 }, + { url = "https://files.pythonhosted.org/packages/6d/db/ddb11011826ed7db9d0e485d13df79b58586bfdec56e5c84a928a9a78c1c/zstandard-0.25.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bfc4e20784722098822e3eee42b8e576b379ed72cca4a7cb856ae733e62192ea", size = 5063001 }, + { url = "https://files.pythonhosted.org/packages/db/00/87466ea3f99599d02a5238498b87bf84a6348290c19571051839ca943777/zstandard-0.25.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:457ed498fc58cdc12fc48f7950e02740d4f7ae9493dd4ab2168a47c93c31298e", size = 5394120 }, + { url = "https://files.pythonhosted.org/packages/2b/95/fc5531d9c618a679a20ff6c29e2b3ef1d1f4ad66c5e161ae6ff847d102a9/zstandard-0.25.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:fd7a5004eb1980d3cefe26b2685bcb0b17989901a70a1040d1ac86f1d898c551", size = 5451230 }, + { url = "https://files.pythonhosted.org/packages/63/4b/e3678b4e776db00f9f7b2fe58e547e8928ef32727d7a1ff01dea010f3f13/zstandard-0.25.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8e735494da3db08694d26480f1493ad2cf86e99bdd53e8e9771b2752a5c0246a", size = 5547173 }, + { url = "https://files.pythonhosted.org/packages/4e/d5/ba05ed95c6b8ec30bd468dfeab20589f2cf709b5c940483e31d991f2ca58/zstandard-0.25.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3a39c94ad7866160a4a46d772e43311a743c316942037671beb264e395bdd611", size = 5046736 }, + { url = "https://files.pythonhosted.org/packages/50/d5/870aa06b3a76c73eced65c044b92286a3c4e00554005ff51962deef28e28/zstandard-0.25.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:172de1f06947577d3a3005416977cce6168f2261284c02080e7ad0185faeced3", size = 5576368 }, + { url = "https://files.pythonhosted.org/packages/5d/35/398dc2ffc89d304d59bc12f0fdd931b4ce455bddf7038a0a67733a25f550/zstandard-0.25.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3c83b0188c852a47cd13ef3bf9209fb0a77fa5374958b8c53aaa699398c6bd7b", size = 4954022 }, + { url = "https://files.pythonhosted.org/packages/9a/5c/36ba1e5507d56d2213202ec2b05e8541734af5f2ce378c5d1ceaf4d88dc4/zstandard-0.25.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1673b7199bbe763365b81a4f3252b8e80f44c9e323fc42940dc8843bfeaf9851", size = 5267889 }, + { url = "https://files.pythonhosted.org/packages/70/e8/2ec6b6fb7358b2ec0113ae202647ca7c0e9d15b61c005ae5225ad0995df5/zstandard-0.25.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:0be7622c37c183406f3dbf0cba104118eb16a4ea7359eeb5752f0794882fc250", size = 5433952 }, + { url = "https://files.pythonhosted.org/packages/7b/01/b5f4d4dbc59ef193e870495c6f1275f5b2928e01ff5a81fecb22a06e22fb/zstandard-0.25.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:5f5e4c2a23ca271c218ac025bd7d635597048b366d6f31f420aaeb715239fc98", size = 5814054 }, + { url = "https://files.pythonhosted.org/packages/b2/e5/fbd822d5c6f427cf158316d012c5a12f233473c2f9c5fe5ab1ae5d21f3d8/zstandard-0.25.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f187a0bb61b35119d1926aee039524d1f93aaf38a9916b8c4b78ac8514a0aaf", size = 5360113 }, + { url = "https://files.pythonhosted.org/packages/8e/e0/69a553d2047f9a2c7347caa225bb3a63b6d7704ad74610cb7823baa08ed7/zstandard-0.25.0-cp313-cp313-win32.whl", hash = "sha256:7030defa83eef3e51ff26f0b7bfb229f0204b66fe18e04359ce3474ac33cbc09", size = 436936 }, + { url = "https://files.pythonhosted.org/packages/d9/82/b9c06c870f3bd8767c201f1edbdf9e8dc34be5b0fbc5682c4f80fe948475/zstandard-0.25.0-cp313-cp313-win_amd64.whl", hash = "sha256:1f830a0dac88719af0ae43b8b2d6aef487d437036468ef3c2ea59c51f9d55fd5", size = 506232 }, + { url = "https://files.pythonhosted.org/packages/d4/57/60c3c01243bb81d381c9916e2a6d9e149ab8627c0c7d7abb2d73384b3c0c/zstandard-0.25.0-cp313-cp313-win_arm64.whl", hash = "sha256:85304a43f4d513f5464ceb938aa02c1e78c2943b29f44a750b48b25ac999a049", size = 462671 }, + { url = "https://files.pythonhosted.org/packages/3d/5c/f8923b595b55fe49e30612987ad8bf053aef555c14f05bb659dd5dbe3e8a/zstandard-0.25.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e29f0cf06974c899b2c188ef7f783607dbef36da4c242eb6c82dcd8b512855e3", size = 795887 }, + { url = "https://files.pythonhosted.org/packages/8d/09/d0a2a14fc3439c5f874042dca72a79c70a532090b7ba0003be73fee37ae2/zstandard-0.25.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:05df5136bc5a011f33cd25bc9f506e7426c0c9b3f9954f056831ce68f3b6689f", size = 640658 }, + { url = "https://files.pythonhosted.org/packages/5d/7c/8b6b71b1ddd517f68ffb55e10834388d4f793c49c6b83effaaa05785b0b4/zstandard-0.25.0-cp314-cp314-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:f604efd28f239cc21b3adb53eb061e2a205dc164be408e553b41ba2ffe0ca15c", size = 5379849 }, + { url = "https://files.pythonhosted.org/packages/a4/86/a48e56320d0a17189ab7a42645387334fba2200e904ee47fc5a26c1fd8ca/zstandard-0.25.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:223415140608d0f0da010499eaa8ccdb9af210a543fac54bce15babbcfc78439", size = 5058095 }, + { url = "https://files.pythonhosted.org/packages/f8/ad/eb659984ee2c0a779f9d06dbfe45e2dc39d99ff40a319895df2d3d9a48e5/zstandard-0.25.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2e54296a283f3ab5a26fc9b8b5d4978ea0532f37b231644f367aa588930aa043", size = 5551751 }, + { url = "https://files.pythonhosted.org/packages/61/b3/b637faea43677eb7bd42ab204dfb7053bd5c4582bfe6b1baefa80ac0c47b/zstandard-0.25.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ca54090275939dc8ec5dea2d2afb400e0f83444b2fc24e07df7fdef677110859", size = 6364818 }, + { url = "https://files.pythonhosted.org/packages/31/dc/cc50210e11e465c975462439a492516a73300ab8caa8f5e0902544fd748b/zstandard-0.25.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e09bb6252b6476d8d56100e8147b803befa9a12cea144bbe629dd508800d1ad0", size = 5560402 }, + { url = "https://files.pythonhosted.org/packages/c9/ae/56523ae9c142f0c08efd5e868a6da613ae76614eca1305259c3bf6a0ed43/zstandard-0.25.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a9ec8c642d1ec73287ae3e726792dd86c96f5681eb8df274a757bf62b750eae7", size = 4955108 }, + { url = "https://files.pythonhosted.org/packages/98/cf/c899f2d6df0840d5e384cf4c4121458c72802e8bda19691f3b16619f51e9/zstandard-0.25.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:a4089a10e598eae6393756b036e0f419e8c1d60f44a831520f9af41c14216cf2", size = 5269248 }, + { url = "https://files.pythonhosted.org/packages/1b/c0/59e912a531d91e1c192d3085fc0f6fb2852753c301a812d856d857ea03c6/zstandard-0.25.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:f67e8f1a324a900e75b5e28ffb152bcac9fbed1cc7b43f99cd90f395c4375344", size = 5430330 }, + { url = "https://files.pythonhosted.org/packages/a0/1d/7e31db1240de2df22a58e2ea9a93fc6e38cc29353e660c0272b6735d6669/zstandard-0.25.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:9654dbc012d8b06fc3d19cc825af3f7bf8ae242226df5f83936cb39f5fdc846c", size = 5811123 }, + { url = "https://files.pythonhosted.org/packages/f6/49/fac46df5ad353d50535e118d6983069df68ca5908d4d65b8c466150a4ff1/zstandard-0.25.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4203ce3b31aec23012d3a4cf4a2ed64d12fea5269c49aed5e4c3611b938e4088", size = 5359591 }, + { url = "https://files.pythonhosted.org/packages/c2/38/f249a2050ad1eea0bb364046153942e34abba95dd5520af199aed86fbb49/zstandard-0.25.0-cp314-cp314-win32.whl", hash = "sha256:da469dc041701583e34de852d8634703550348d5822e66a0c827d39b05365b12", size = 444513 }, + { url = "https://files.pythonhosted.org/packages/3a/43/241f9615bcf8ba8903b3f0432da069e857fc4fd1783bd26183db53c4804b/zstandard-0.25.0-cp314-cp314-win_amd64.whl", hash = "sha256:c19bcdd826e95671065f8692b5a4aa95c52dc7a02a4c5a0cac46deb879a017a2", size = 516118 }, + { url = "https://files.pythonhosted.org/packages/f0/ef/da163ce2450ed4febf6467d77ccb4cd52c4c30ab45624bad26ca0a27260c/zstandard-0.25.0-cp314-cp314-win_arm64.whl", hash = "sha256:d7541afd73985c630bafcd6338d2518ae96060075f9463d7dc14cfb33514383d", size = 476940 }, ] diff --git a/visualizations/interactive_graph.py b/visualizations/interactive_graph.py index b7175b62..71a500eb 100644 --- a/visualizations/interactive_graph.py +++ b/visualizations/interactive_graph.py @@ -1,20 +1,19 @@ """ Interactive HTML graph visualization of memory system. -Uses pyvis to create a smooth, interactive network graph that can be +Uses Cytoscape.js to create a performant, interactive network graph that can be explored in the browser. Shows all memory units and their links with weights. """ import psycopg2 from dotenv import load_dotenv import os -from pyvis.network import Network -import networkx as nx +import json load_dotenv() def create_interactive_graph(): - """Create an interactive HTML graph visualization.""" + """Create an interactive HTML graph visualization using Cytoscape.js.""" # Connect to database conn = psycopg2.connect(os.getenv('DATABASE_URL')) @@ -61,235 +60,532 @@ def create_interactive_graph(): entity_map[unit_id] = [] entity_map[unit_id].append(f"{entity_name} ({entity_type})") - # Create pyvis network - net = Network( - height="900px", - width="100%", - bgcolor="#ffffff", - font_color="#000000", - heading="Entity-Aware Memory Graph - Interactive Visualization" - ) - - # Configure physics for smooth layout with performance optimizations - net.set_options(""" - { - "nodes": { - "font": { - "size": 14, - "face": "Tahoma" - }, - "borderWidth": 2, - "borderWidthSelected": 3 - }, - "edges": { - "smooth": { - "enabled": false - }, - "font": { - "size": 10, - "align": "middle" - } - }, - "physics": { - "enabled": true, - "stabilization": { - "enabled": true, - "iterations": 100, - "updateInterval": 10 - }, - "barnesHut": { - "gravitationalConstant": -12000, - "centralGravity": 0.2, - "springLength": 350, - "springConstant": 0.02, - "damping": 0.09, - "avoidOverlap": 0.8 - }, - "solver": "barnesHut", - "timestep": 0.5, - "adaptiveTimestep": true - }, - "interaction": { - "hover": true, - "tooltipDelay": 100, - "navigationButtons": true, - "keyboard": true - } - } - """) + # Build Cytoscape.js graph data + cy_nodes = [] + cy_edges = [] # Add nodes for unit_id, text, event_date, context in units: - # Truncate text for display - display_text = text[:50] + "..." if len(text) > 50 else text - - # Get entities entities = entity_map.get(unit_id, []) - entity_str = "\\n".join(entities) if entities else "No entities" - - # Build node label and title (hover) - label = display_text - title = f""" - Text: {text}
- Date: {event_date.date()}
- Context: {context}
- Entities: {entity_str} - """ + entity_count = len(entities) # Color by entity count - if len(entities) == 0: - color = "#e0e0e0" # Gray - size = 20 - elif len(entities) == 1: - color = "#90caf9" # Light blue - size = 25 + if entity_count == 0: + color = "#e0e0e0" + elif entity_count == 1: + color = "#90caf9" else: - color = "#42a5f5" # Dark blue - size = 30 + color = "#42a5f5" - net.add_node( - str(unit_id), - label=label, - title=title, - color=color, - size=size, - shape="box", - font={"color": "#000000"} - ) + cy_nodes.append({ + "data": { + "id": str(unit_id), + "label": text[:50] + "..." if len(text) > 50 else text, + "text": text, + "context": context, + "date": str(event_date.date()), + "entities": ", ".join(entities) if entities else "None", + "color": color + } + }) - # Add edges with colors and weights + # Add edges for from_id, to_id, link_type, weight, entity_name in links: - # Set color and style based on link type + # Set color based on link type if link_type == 'temporal': - color = "#00bcd4" # Cyan - dashes = [5, 5] - width = 0.5 - label = f"T: {weight:.2f}" + color = "#00bcd4" + line_style = "dashed" elif link_type == 'semantic': - color = "#ff69b4" # Pink - dashes = False - width = 0.5 - label = f"S: {weight:.2f}" + color = "#ff69b4" + line_style = "solid" elif link_type == 'entity': - color = "#ffd700" # Gold - dashes = False - width = 0.8 - label = f"{entity_name}: {weight:.2f}" + color = "#ffd700" + line_style = "solid" else: color = "#999999" - dashes = False - width = 0.5 - label = f"{weight:.2f}" + line_style = "solid" - net.add_edge( - str(from_id), - str(to_id), - value=weight * 1, # Scale for visual thickness - color=color, - dashes=dashes, - width=width, - label=label, - title=f"{link_type.upper()}: {weight:.3f}" + (f" (Entity: {entity_name})" if entity_name else "") - ) + cy_edges.append({ + "data": { + "id": f"{from_id}-{to_id}-{link_type}", + "source": str(from_id), + "target": str(to_id), + "weight": weight, + "linkType": link_type, + "entityName": entity_name or "", + "color": color, + "lineStyle": line_style + } + }) - # Add legend as HTML - legend_html = """ -
-

Legend

+ graph_data = {"nodes": cy_nodes, "edges": cy_edges} -

Link Types:

-
-
- - Temporal - Time-based (cyan, dashed) + # Build table rows for table view + table_rows = [] + for unit_id, text, event_date, context in units: + entities = entity_map.get(unit_id, []) + entity_str = ", ".join(entities) if entities else "None" + table_rows.append(f""" + + {str(unit_id)[:8]}... + {text} + {context} + {event_date.date()} + {entity_str} + + """) + + # Generate HTML with Cytoscape.js + html_content = f""" + + + + Memory Graph - Interactive Visualization + + + + + +
+
+ + +
+ +
+
+
+
+ + +
+
+ + +
+ + +
-
- - Semantic - Meaning-based (pink, solid) -
-
- - Entity - Same entity (gold) +
+
+

Legend

+

Link Types:

+
+
+ Temporal +
+
+
+ Semantic +
+
+
+ Entity +
+

Nodes:

+
+
+ No entities +
+
+
+ 1 entity +
+
+
+ 2+ entities +
-

Node Colors:

-
-
- - Gray - No entities +
+

Memory Units ({len(units)})

+ +
+ + + + + + + + + + + + {''.join(table_rows)} + +
IDTextContextDateEntities
-
- - Light Blue - 1 entity -
-
- - Dark Blue - 2+ entities -
-
- -
- Tip: Hover over nodes/edges for details
- Controls: Drag to move, scroll to zoom
- """ - # Generate the HTML - output_file = "memory_graph_interactive.html" - net.save_graph(output_file) + - """ - html_content = html_content.replace('', physics_script + '') + + +""" - # Write back - with open(output_file, 'w') as f: + # Write HTML file + output_file = "memory_graph_interactive.html" + with open(output_file, 'w', encoding='utf-8') as f: f.write(html_content) + # Print summary print(f"\n{'='*80}") - print("INTERACTIVE GRAPH GENERATED") + print("INTERACTIVE GRAPH GENERATED (Cytoscape.js)") print(f"{'='*80}") print(f"\nFile: {output_file}") print(f"Units: {len(units)}") print(f"Links: {len(links)}") print("\nFeatures:") - print(" • Smooth, physics-based layout") - print(" • Interactive - drag nodes, zoom, pan") - print(" • Hover for details on nodes and edges") - print(" • Color-coded by link type and entity count") - print(" • Built-in navigation controls") + print(" • Tab 1: Graph View - Fast interactive network (Cytoscape.js)") + print(" - Limit nodes (default: 50) for better performance") + print(" - Choose layout: Circle (fast), Grid (fast), or Force-directed") + print(" - Drag nodes, zoom, pan") + print(" - Hover for details") + print(" • Tab 2: Table View - Searchable memory units") + print(" - Filter by text, context, or entities") + print(" - Case-insensitive search") + print(" - Shows ALL nodes") print(f"\n{'='*80}") print(f"✓ Open {output_file} in your browser to explore!") + print(f" TIP: Start with 50 nodes and Circle layout for best performance") print(f"{'='*80}\n") diff --git a/visualizations/memory_graph_interactive.html b/visualizations/memory_graph_interactive.html index 7d1571ba..2a2463a8 100644 --- a/visualizations/memory_graph_interactive.html +++ b/visualizations/memory_graph_interactive.html @@ -1,189 +1,2775 @@ + + - - - - - - - - -
-

Entity-Aware Memory Graph - Interactive Visualization

-
+ + Memory Graph - Interactive Visualization + + + - + .tab-content.active { + display: block; + } + #cy { + width: 100%; + height: 800px; + background: #ffffff; + } - -
-

Legend

+ #graph-tab { + position: relative; + } -

Link Types:

-
-
- - Temporal - Time-based (cyan, dashed) + #table-tab { + padding: 20px; + } + + .legend { + position: absolute; + top: 20px; + left: 20px; + background: white; + padding: 15px; + border: 2px solid #333; + border-radius: 8px; + box-shadow: 2px 2px 8px rgba(0,0,0,0.3); + z-index: 1000; + max-width: 250px; + } + + .legend h3 { + margin-top: 0; + border-bottom: 2px solid #333; + padding-bottom: 5px; + } + + .legend-item { + margin: 8px 0; + display: flex; + align-items: center; + } + + .legend-line { + width: 30px; + height: 2px; + margin-right: 10px; + } + + .legend-node { + width: 20px; + height: 20px; + margin-right: 10px; + border: 1px solid #999; + border-radius: 3px; + } + + #table-filter { + width: 100%; + max-width: 600px; + padding: 10px; + margin-bottom: 15px; + border: 2px solid #ccc; + border-radius: 4px; + font-size: 14px; + box-sizing: border-box; + } + + #memory-table { + width: 100%; + border-collapse: collapse; + font-size: 13px; + max-width: 1400px; + } + + #memory-table th { + padding: 10px; + text-align: left; + border: 1px solid #ddd; + background: #f0f0f0; + } + + #memory-table td { + padding: 8px; + border: 1px solid #ddd; + } + + .tooltip { + position: absolute; + background: white; + border: 2px solid #333; + border-radius: 4px; + padding: 10px; + box-shadow: 2px 2px 8px rgba(0,0,0,0.3); + max-width: 300px; + font-size: 12px; + pointer-events: none; + z-index: 9999; + } + + + +
+
+ + +
+ +
+
+
+
+ + +
+
+ + +
+ + +
-
- - Semantic - Meaning-based (pink, solid) -
-
- - Entity - Same entity (gold) +
+
+

Legend

+

Link Types:

+
+
+ Temporal +
+
+
+ Semantic +
+
+
+ Entity +
+

Nodes:

+
+
+ No entities +
+
+
+ 1 entity +
+
+
+ 2+ entities +
-

Node Colors:

-
-
- - Gray - No entities +
+

Memory Units (294)

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDTextContextDateEntities
84668df1...A friend hand‑painted a bowl for Caroline on her 18th birthday ten years ago, and the bowl's pattern and colors remind her of art and self‑expression.Conversation session between Caroline and Melanie2013-06-27Caroline (PERSON)
db2171ee...Melanie has been married for five years, with the marriage beginning around 2018-06-09.Conversation session between Caroline and Melanie2018-06-09Melanie (PERSON)
4efedc9a...Caroline started playing acoustic guitar around 2018-08-28, five years ago, and uses it to express emotions and escape.Conversation session between Caroline and Melanie2018-08-28None
3b03a48d...Caroline moved from her home country approximately four years ago on 2019-06-09.Conversation session between Caroline and Melanie2019-06-09Caroline (ORG)
a07530e7...Caroline began her gender transition three years ago on 2020-06-09.Conversation session between Caroline and Melanie2020-06-09None
08a28d1e...Melanie painted a lake sunrise artwork in 2022, and she says the painting is special to her.Conversation session between Caroline and Melanie2022-05-08Melanie (PERSON)
ae4d3b8d...On 2022-07-12, Melanie read a book that reminded her to always pursue her dreams.Conversation session between Caroline and Melanie2022-07-12Melanie (PERSON)
6805004e...Melanie's family went on a camping trip in August 2022 and saw the Perseid meteor shower on August 12, 2022, making wishes while watching the sky light up with streaks of light.Conversation session between Caroline and Melanie2022-08-12Perseid (ORG), Melanie (PERSON)
af8180ca...Caroline and Melanie attended a Pride festival together in 2022, describing it as a blast with supportive friends.Conversation session between Caroline and Melanie2022-08-17Caroline (ORG), Pride (PRODUCT), Melanie (PERSON)
6dd31607...Melanie's friend (a buddy of Melanie) adopted a child after a long process in 2022, and the friend is now super happy with the new kid.Conversation session between Caroline and Melanie2022-10-13Melanie (PERSON)
0fe08d8b...The LGBTQ support group made Caroline feel accepted and gave her courage to embrace herself on 2023-05-07.Conversation session between Caroline and Melanie2023-05-07Caroline (ORG)
1e8a9e7c...Caroline attended an LGBTQ support group on 2023-05-07 and described the experience as powerful.Conversation session between Caroline and Melanie2023-05-07Caroline (PERSON)
4a4b6853...During the LGBTQ support group on 2023-05-07, Caroline heard inspiring transgender stories, which made her feel happy and thankful for the support.Conversation session between Caroline and Melanie2023-05-07Caroline (ORG)
c63b1b3c...Melanie expressed the opinion that Caroline would be a great counselor because of her empathy and understanding.Conversation session between Caroline and Melanie2023-05-08Melanie (PERSON), Caroline (PERSON)
eb82f8f8...Melanie is currently swamped with caring for her children and her work, indicating she feels very busy.Conversation session between Caroline and Melanie2023-05-08Melanie (PERSON)
001940c8...Caroline observed that the colors in Melanie's lake sunrise painting blend nicely.Conversation session between Caroline and Melanie2023-05-08Melanie (PERSON)
2b6b806a...Caroline believes that relaxing and expressing oneself is key to wellbeing.Conversation session between Caroline and Melanie2023-05-08None
dab4a6e7...Melanie believes that taking care of oneself is vital.Conversation session between Caroline and Melanie2023-05-08Melanie (PERSON)
2eb6de66...Melanie said she is going to go swimming with her kids after the conversation.Conversation session between Caroline and Melanie2023-05-08Melanie (PERSON)
b6873819...Caroline said she is going to do some research after the conversation.Conversation session between Caroline and Melanie2023-05-08Caroline (ORG)
47cfe483...Melanie uses painting as a fun way to express her feelings, be creative, and relax after a long day.Conversation session between Caroline and Melanie2023-05-08Melanie (PERSON)
bc68a8e2...Caroline is interested in pursuing a career in counseling or mental health so she can support people with similar issues.Conversation session between Caroline and Melanie2023-05-08Caroline (ORG)
c56cff23...Caroline plans to continue her education and explore career options, expressing excitement about these next steps.Conversation session between Caroline and Melanie2023-05-08None
7fb1e463...Melanie ran a charity race for mental health on Saturday, May 20, 2023, and found it rewarding and thought‑provoking, which made her reflect on the importance of self‑care.Conversation session between Caroline and Melanie2023-05-20Melanie (PERSON), self‑care (ORG)
6838c0ae...Caroline said she is thrilled to make a family for kids who need one, acknowledging that it will be tough as a single parent but she is up for the challenge.Conversation session between Caroline and Melanie2023-05-25Caroline (ORG)
effe659e...Caroline shared that she has found an adoption agency she is looking into and that she feels hopeful and optimistic about it.Conversation session between Caroline and Melanie2023-05-25None
54e089c1...Melanie stated that she is starting to realize that self‑care is really important and that looking after herself enables her to better look after her family.Conversation session between Caroline and Melanie2023-05-25Melanie (PERSON), self‑care (ORG)
16a3c809...Melanie said she is carving out daily “me‑time” each day, which includes running, reading, or playing her violin, to refresh herself and stay present for her family.Conversation session between Caroline and Melanie2023-05-25Melanie (PERSON)
b6feca7a...Caroline said she is researching adoption agencies because she dreams of having a family and giving a loving home to children who need it.Conversation session between Caroline and Melanie2023-05-25Caroline (ORG)
14ed0c9a...Caroline said taking care of ourselves is important even if not always easy, and praised Melanie for prioritizing self‑care.Conversation session between Caroline and Melanie2023-05-25self‑care (ORG), Melanie (PERSON), Caroline (ORG)
8c58e428...Melanie expressed that she is still a work in progress but doing her best.Conversation session between Caroline and Melanie2023-05-25Melanie (PERSON)
1e167793...Caroline explained that she chose that adoption agency because it helps LGBTQ+ individuals with adoption, and its inclusivity and support resonated with her.Conversation session between Caroline and Melanie2023-05-25Caroline (ORG)
e31f0cfa...Caroline expressed that her goal is to give kids a loving home and that she is grateful for support from friends and mentors as she begins the hard work of turning her adoption dream into reality.Conversation session between Caroline and Melanie2023-05-25Caroline (PERSON)
29655a13...Melanie asked Caroline what made her pick the adoption agency.Conversation session between Caroline and Melanie2023-05-25Melanie (PERSON), Caroline (PERSON)
00281f58...Melanie praised Caroline’s decision, saying she is doing something amazing by creating a family for kids in need and that Caroline will be an awesome mom.Conversation session between Caroline and Melanie2023-05-25Melanie (PERSON), Caroline (ORG), Caroline (PERSON)
30c218c6...Melanie thanked Caroline and said the charity race was thought‑provoking.Conversation session between Caroline and Melanie2023-05-25Caroline (PERSON), Melanie (PERSON)
25e586d4...Caroline replied that she chose the agency because they help LGBTQ+ folks with adoption.Conversation session between Caroline and Melanie2023-05-25Caroline (ORG)
f411518a...Caroline thanked Melanie for her kind words and said she will do her best to ensure the children have a safe and loving home.Conversation session between Caroline and Melanie2023-05-25Melanie (PERSON)
8c50b1d7...Melanie affirmed that Caroline has a caring heart and that the children will receive love and stability.Conversation session between Caroline and Melanie2023-05-25Caroline (ORG), Melanie (PERSON)
c568bba4...Caroline expressed pride in Melanie for taking part in the charity race.Conversation session between Caroline and Melanie2023-05-25Melanie (PERSON)
c54709fa...During the school event, Caroline observed positive reactions from the audience.Conversation session between Caroline and Melanie2023-06-02Caroline (PERSON)
623f45ac...Caroline shared a photo taken during a meetup with Melanie last week.Conversation session between Caroline and Melanie2023-06-02Melanie (PERSON)
9b1d384d...Caroline gave a talk at a school event about her transgender journey and encouraged students to get involved in the LGBTQ community.Conversation session between Caroline and Melanie2023-06-02None
296a4c2c...Caroline felt powerful while delivering her talk at the school event.Conversation session between Caroline and Melanie2023-06-02None
3b65657b...Audience members were inspired by Caroline's talk and expressed desire to become better allies.Conversation session between Caroline and Melanie2023-06-02Caroline (PERSON)
ecddbb67...Caroline shared details of her personal journey, struggles, and personal development since coming out during the school talk.Conversation session between Caroline and Melanie2023-06-02None
853bf965...The shared photo depicted Caroline and Melanie (and possibly other friends) meeting up last week.Conversation session between Caroline and Melanie2023-06-02Melanie (PERSON), Caroline (PERSON)
a86d1427...Caroline highlighted the importance of sharing personal experiences to promote understanding and acceptance.Conversation session between Caroline and Melanie2023-06-09Caroline (ORG)
dd5340a7...Melanie stated that her husband and children keep her motivated.Conversation session between Caroline and Melanie2023-06-09Melanie (PERSON)
f5b06217...Melanie described a recent family gathering where they played games, ate good food, and hung out together.Conversation session between Caroline and Melanie2023-06-09Melanie (PERSON)
e3fed70e...Melanie expressed pride and support for Caroline's effort to spread LGBTQ awareness at the school event.Conversation session between Caroline and Melanie2023-06-09Caroline (PERSON), LGBTQ (PERSON), Melanie (PERSON)
9574da60...Caroline committed to continue using her voice to create change and lift others up.Conversation session between Caroline and Melanie2023-06-09None
9664c7b8...Caroline mentioned feeling blessed with love and support throughout her transition journey.Conversation session between Caroline and Melanie2023-06-09Caroline (ORG)
eb08c29e...Caroline has known her current group of friends for four years, since moving from her home country around 2019-06-09.Conversation session between Caroline and Melanie2023-06-09Caroline (ORG)
8feaaee2...Melanie expressed that she cherishes time with her family and feels alive and happy during those moments.Conversation session between Caroline and Melanie2023-06-09Melanie (PERSON)
da8729ba...Caroline referenced a past tough breakup that occurred before her current support system.Conversation session between Caroline and Melanie2023-06-09Caroline (ORG)
61ecb2f4...Caroline agreed that hanging with loved ones brings happiness, gratitude, and that family is everything.Conversation session between Caroline and Melanie2023-06-09Caroline (ORG)
740ef190...Melanie noted that sharing vulnerable stories helps people bond and understand each other.Conversation session between Caroline and Melanie2023-06-09Melanie (PERSON)
4b70b765...Caroline expressed gratitude for being able to give a voice to the trans community.Conversation session between Caroline and Melanie2023-06-09None
0aa11340...Caroline identified her friends, family, and mentors as her sources of motivation.Conversation session between Caroline and Melanie2023-06-09None
90ba83c2...Caroline thanked Melanie for her backing and support.Conversation session between Caroline and Melanie2023-06-09Melanie (PERSON)
b8b1da84...Melanie said she wants to be courageous for her family, who motivate her and give her love.Conversation session between Caroline and Melanie2023-06-09Melanie (PERSON)
f0c183ae...Caroline emphasized the necessity of conversations about gender identity and inclusion.Conversation session between Caroline and Melanie2023-06-09None
7adc180d...Melanie praised Caroline's inspiring impact on others.Conversation session between Caroline and Melanie2023-06-09Melanie (PERSON), Caroline (PERSON)
4abfd08f...Caroline expressed happiness for Melanie's family moments and congratulated her on her wedding day.Conversation session between Caroline and Melanie2023-06-09Melanie (PERSON)
bb0ba2a7...Caroline described the LGBT pride event in June 2023 as encouraging, with abundant love and acceptance.Conversation session between Caroline and Melanie2023-06-15LGBT (ORG)
58920dae...Caroline observed her mentee's face light up with joy upon seeing support at the LGBT pride event in June 2023.Conversation session between Caroline and Melanie2023-06-15LGBT (ORG)
10d92dc2...Caroline and her mentee attended an LGBT pride event in June 2023 (approximately June 15) and had a great time.Conversation session between Caroline and Melanie2023-06-15LGBT (ORG)
cf6654cb...During the mountain camping trip, Melanie's family roasted marshmallows around a campfire.Conversation session between Caroline and Melanie2023-06-20Melanie (PERSON)
8956c941...During the mountain camping trip, Melanie's family reached a viewpoint at the top with an amazing view.Conversation session between Caroline and Melanie2023-06-20Melanie (PERSON)
c213873d...During the mountain camping trip, Melanie's family went on a hike.Conversation session between Caroline and Melanie2023-06-20Melanie (PERSON)
579375c6...During the mountain camping trip, Melanie's family explored nature.Conversation session between Caroline and Melanie2023-06-20Melanie (PERSON)
a3e155a9...Melanie took her family camping in the mountains last week.Conversation session between Caroline and Melanie2023-06-20Melanie (PERSON)
c2def070...At the LGBTQ+ counseling workshop, Caroline observed passionate professionals who were dedicated to creating safe spaces for people like her.Conversation session between Caroline and Melanie2023-06-23Caroline (PERSON)
78e6378d...Caroline attended an LGBTQ+ counseling workshop on Friday, June 23, 2023.Conversation session between Caroline and Melanie2023-06-23Caroline (PERSON)
4e40dc01...At the LGBTQ+ counseling workshop, participants discussed various therapeutic methods for working with trans people.Conversation session between Caroline and Melanie2023-06-23None
e92f48a8...Caroline attended a pride parade approximately three weeks earlier on June 24, 2023, participated actively, and felt accepted, happy, proud, grateful, and inspired by the community.Conversation session between Caroline and Melanie2023-06-24Caroline (ORG)
39aa1010...Melanie mentioned that her kids are excited about summer break and that the family is thinking about going camping in June 2023.Conversation session between Caroline and Melanie2023-06-25Melanie (PERSON)
e5397d45...Caroline attended an LGBTQ+ pride parade, felt a sense of belonging, and observed that the LGBTQ+ community has grown.Conversation session between Caroline and Melanie2023-06-26Caroline (PERSON)
0b8fbb46...Caroline expressed excitement about using her personal story to give back to the community.Conversation session between Caroline and Melanie2023-06-26Caroline (ORG)
8aecf38f...The experience at the pride parade motivated Caroline to consider a career in counseling and mental health to help others.Conversation session between Caroline and Melanie2023-06-26Caroline (ORG)
822f8f68...Caroline's grandmother, who gave her the necklace, is from Sweden, Caroline's home country.Conversation session between Caroline and Melanie2023-06-27Sweden (GPE), Caroline (PERSON), Caroline (ORG)
9261eb65...Melanie believes that personal items can hold deep meaning for individuals.Conversation session between Caroline and Melanie2023-06-27Melanie (PERSON)
5407ad19...Melanie believes that family time matters to her.Conversation session between Caroline and Melanie2023-06-27Melanie (PERSON)
46b3991f...Melanie has two younger kids who love nature.Conversation session between Caroline and Melanie2023-06-27Melanie (PERSON)
b44e3d6d...Caroline is passionate about creating a safe, inviting place for people to grow.Conversation session between Caroline and Melanie2023-06-27Caroline (ORG)
ad56b9e9...Caroline states that counseling and support groups improved her life, which motivated her to care more about mental health and self‑understanding.Conversation session between Caroline and Melanie2023-06-27None
0dd690fb...Caroline believes that her own life journey and the support she received made a huge difference in her well‑being.Conversation session between Caroline and Melanie2023-06-27None
c7c6406f...Caroline intends to work specifically with trans people, helping them accept themselves and supporting their mental health.Conversation session between Caroline and Melanie2023-06-27None
27373bd4...Caroline has been researching counseling and mental health as a career to help people who have experienced similar challenges to her.Conversation session between Caroline and Melanie2023-06-27Caroline (ORG)
a22203c3...Caroline received a necklace as a gift from her grandmother in Sweden when she was young, and the necklace symbolizes love, faith, and strength, serving as a reminder of her roots and family support.Conversation session between Caroline and Melanie2023-06-27Caroline (ORG), Sweden (GPE)
7d65f3c6...Melanie expressed that Caroline's dedication to helping others is inspiring.Conversation session between Caroline and Melanie2023-06-27Caroline (PERSON), Melanie (PERSON)
c12d93c6...Melanie congratulated Caroline for pursuing what she truly cares about.Conversation session between Caroline and Melanie2023-06-27Melanie (PERSON), Caroline (PERSON)
13d1d7ea...Caroline and her friends/family had a picnic last week.Conversation session between Caroline and Melanie2023-06-29None
41d4b4de...Melanie signed up for a pottery class as a form of therapy and creative self‑expression.Conversation session between Caroline and Melanie2023-07-02Melanie (PERSON)
d838fadd...Melanie described pottery as calming, therapeutic, and a way to express emotions.Conversation session between Caroline and Melanie2023-07-02Melanie (PERSON)
4f53d7b8...Melanie expressed excitement about future possibilities in pottery.Conversation session between Caroline and Melanie2023-07-03Melanie (PERSON)
de9d34a8...Caroline intends to keep Melanie updated about her upcoming transgender conference.Conversation session between Caroline and Melanie2023-07-03Melanie (PERSON)
8fb29493...Caroline is learning to play the piano as a creative activity.Conversation session between Caroline and Melanie2023-07-03None
c245c117...Melanie stated that pottery is a major part of her life, not just a hobby, and that working with clay brings her great joy.Conversation session between Caroline and Melanie2023-07-03Melanie (PERSON)
86fa0797...Caroline plans to attend a transgender conference in July 2023 to meet community members and learn about advocacy.Conversation session between Caroline and Melanie2023-07-03None
085950e6...Melanie created a black‑and‑white bowl in her pottery class, which required effort and made her feel proud.Conversation session between Caroline and Melanie2023-07-03Melanie (PERSON)
cef24409...Melanie took her children to a museum yesterday, spending time with them and enjoying their excitement at the dinosaur exhibit.Conversation session between Caroline and Melanie2023-07-05Melanie (PERSON)
17eb1bce...Melanie recalled that she loved reading the book "Charlotte's Web" when she was a child.Conversation session between Caroline and Melanie2023-07-06Melanie (PERSON)
1fe174fd...Caroline is creating a library of children's books to use when she has kids in the future.Conversation session between Caroline and Melanie2023-07-06None
d5fc4716...Caroline owns a collection of many children's books, including classics, multicultural stories, and educational titles.Conversation session between Caroline and Melanie2023-07-06Caroline (ORG)
5eacfbb1...Melanie shared a photo of her family camping at the beach, noting that the experience brings the family closer together.Conversation session between Caroline and Melanie2023-07-06Melanie (PERSON)
732c00a6...Caroline viewed a picture that Melanie shared of the museum visit with her kids.Conversation session between Caroline and Melanie2023-07-06Melanie (PERSON)
ac867b49...Melanie commented on and viewed a photo that Caroline shared of the picnic.Conversation session between Caroline and Melanie2023-07-06Melanie (PERSON), Caroline (ORG)
9e604e93...Caroline has been researching counseling and mental health work since her last conversation with Melanie, expressing a passion for helping people and making a positive impact.Conversation session between Caroline and Melanie2023-07-06Melanie (PERSON), Caroline (ORG)
59bc760e...Melanie went camping with her family during the weekend of July 8–9, 2023.Conversation session between Caroline and Melanie2023-07-08Melanie (PERSON)
6aeafc72...Caroline attended an LGBTQ conference on 2023-07-10, describing it as special and welcoming.Conversation session between Caroline and Melanie2023-07-10Caroline (PERSON)
5fb0f6f7...Caroline felt totally accepted at the LGBTQ conference on 2023-07-10.Conversation session between Caroline and Melanie2023-07-10None
25c419f5...Caroline expressed gratitude for the LGBTQ community on 2023-07-10, emphasizing the importance of fighting for trans rights and spreading awareness.Conversation session between Caroline and Melanie2023-07-10None
650fe33d...At the LGBTQ conference on 2023-07-10, Caroline met and connected with people who have experienced similar gender‑identity journeys.Conversation session between Caroline and Melanie2023-07-10Caroline (PERSON)
7a66783b...On 2023-07-12, Melanie has a dog (pup) and a cat, and she shared a picture of the cat.Conversation session between Caroline and Melanie2023-07-12Melanie (PERSON)
3c4295ed...Caroline loves reading; she says books guide, motivate, and help her discover her identity, and they remind her to keep going and never give up.Conversation session between Caroline and Melanie2023-07-12None
42a9af42...On 2023-07-12, Melanie's pets are named Luna (dog) and Oliver (cat).Conversation session between Caroline and Melanie2023-07-12Melanie (PERSON), Oliver (PERSON), Luna (PERSON)
4f939db0...Caroline previously struggled with mental health, received helpful support, and realized the importance of having a support system for others.Conversation session between Caroline and Melanie2023-07-12Caroline (ORG)
db42937b...On 2023-07-12, Caroline saw a picture shared by Melanie that increased her appreciation for reading.Conversation session between Caroline and Melanie2023-07-12Caroline (ORG), Melanie (PERSON)
8b30b1e5...On 2023-07-12, Caroline read the book "Becoming Nicole" by Amy Ellis Nutt, found it inspiring about a trans girl and her family, felt connected, and highly recommends it.Conversation session between Caroline and Melanie2023-07-12Amy Ellis Nutt (PERSON), Caroline (ORG)
fde065aa...On 2023-07-12, Melanie purchased new purple shoes intended for running.Conversation session between Caroline and Melanie2023-07-12Melanie (PERSON)
1f21c19d...On 2023-07-12, Melanie has been running farther to de‑stress, which has improved her headspace.Conversation session between Caroline and Melanie2023-07-12Melanie (PERSON)
2440c55b...Melanie believes pets bring joy and comfort.Conversation session between Caroline and Melanie2023-07-12Melanie (PERSON)
8f837449...Melanie believes running improves her mental health, helps de‑stress, and boosts her mood.Conversation session between Caroline and Melanie2023-07-12Melanie (PERSON)
2f7f76eb...Caroline believes the book taught her self‑acceptance, how to find support, that tough times don't last, and that pets bring joy.Conversation session between Caroline and Melanie2023-07-12None
105d4582...On 2023-07-12, Melanie has been running longer since her last conversation with Caroline, using it to destress and clear her mind.Conversation session between Caroline and Melanie2023-07-12Melanie (PERSON), Caroline (PERSON)
34434e86...On 2023-07-12, Caroline was researching counseling and mental‑health job opportunities because she wants people to have someone to talk to.Conversation session between Caroline and Melanie2023-07-12Caroline (PERSON), mental‑health (ORG)
12ed2fc9...On 2023-07-12, Caroline started looking into counseling and mental‑health career options to help others on their personal journeys.Conversation session between Caroline and Melanie2023-07-12mental‑health (ORG), Caroline (PERSON)
3ecdc3ff...During the painting session on the weekend of July 13-14, 2023, Melanie and her children both contributed to the artwork, bonding over the process and chatting about nature.Conversation session between Caroline and Melanie2023-07-13Melanie (PERSON)
28ab7f71...Melanie and her children collected lovely flowers during their weekend painting session on July 13-14, 2023, which they incorporated into the artwork.Conversation session between Caroline and Melanie2023-07-13Melanie (PERSON)
df2fc5b2...Melanie and her children painted a nature-inspired artwork together, completing the latest piece during the weekend of July 13-14, 2023, and used flowers they found as inspiration.Conversation session between Caroline and Melanie2023-07-13Melanie (PERSON)
efe08615...Melanie took her children to a pottery workshop on Friday, July 14, 2023, where they each made their own pots, including a cup, and found the activity fun and therapeutic.Conversation session between Caroline and Melanie2023-07-14Melanie (PERSON)
7db02005...Caroline attended a council meeting about adoption on Friday, July 14, 2023, found it inspiring and emotional, and felt more determined to adopt a child.Conversation session between Caroline and Melanie2023-07-14Caroline (ORG)
0238b02a...The children at Melanie's pottery workshop loved the experience, were excited to get their hands dirty with clay, and created a cup that Melanie showed to Caroline.Conversation session between Caroline and Melanie2023-07-14Melanie (PERSON), Caroline (ORG)
41ae9ca7...Melanie spent a quiet weekend unplugging and hanging out with her children during the weekend of July 15–16, 2023.Conversation session between Caroline and Melanie2023-07-15Melanie (PERSON)
ece6819a...Caroline joined a mentorship program for LGBTQ youth during the weekend of July 15–16, 2023.Conversation session between Caroline and Melanie2023-07-15Caroline (ORG)
242126e2...Caroline shared a photo of a blue vase with Melanie on July 15, 2023, expressing that she loves the blue color because it makes her feel relaxed.Conversation session between Caroline and Melanie2023-07-15Melanie (PERSON)
8a6cdb36...Melanie's wedding featured flowers as part of the decor, which she says bring her joy, represent growth and beauty, and remind her of the special day.Conversation session between Caroline and Melanie2023-07-15Melanie (PERSON)
dcd05bcd...Melanie's family provided love, support, and assistance during her move, helping her through tough times, as mentioned on July 15, 2023.Conversation session between Caroline and Melanie2023-07-15Melanie (PERSON)
3a86475e...Melanie and her family went on another camping trip in a forest, as mentioned on July 15, 2023.Conversation session between Caroline and Melanie2023-07-15Melanie (PERSON)
3d96f6ba...Melanie and her family enjoy hiking in the mountains and exploring forests together, as an ongoing activity mentioned on July 15, 2023.Conversation session between Caroline and Melanie2023-07-15Melanie (PERSON)
ac1f9a8d...Caroline realized she can be herself without fear, having the courage to transition, which she describes as the best part of her journey, mentioned on July 15, 2023.Conversation session between Caroline and Melanie2023-07-15None
07555431...Caroline feels supported by her friends and community, which inspires her and makes her feel accepted, as expressed on July 15, 2023.Conversation session between Caroline and Melanie2023-07-15Caroline (ORG)
a7d6ed4c...Melanie believes flowers bring joy, represent growth and beauty, and remind people to appreciate small moments; she also notes they were important in her wedding decor, as stated on July 15, 2023.Conversation session between Caroline and Melanie2023-07-15Melanie (PERSON)
996ed117...Caroline says her friends and community have her back, providing love and acceptance, as expressed on July 15, 2023.Conversation session between Caroline and Melanie2023-07-15Caroline (PERSON)
ac414e1a...Melanie says creativity and family keep her at peace, as stated on July 15, 2023.Conversation session between Caroline and Melanie2023-07-15Melanie (PERSON)
becd427f...Melanie and her children have been painting together lately, focusing on nature-inspired themes, as an ongoing activity mentioned on July 15, 2023.Conversation session between Caroline and Melanie2023-07-15Melanie (PERSON)
69cd0336...Caroline likes the color blue because it makes her feel relaxed, associates sunflowers with warmth and happiness, and roses with love and beauty, as expressed on July 15, 2023.Conversation session between Caroline and Melanie2023-07-15None
9e69f1f7...Caroline missed the city pride parade that took place on July 15, 2023.Conversation session between Caroline and Melanie2023-07-15Caroline (ORG)
a75a5494...The city held a pride parade on the weekend of July 15, 2023, with many people marching, waving flags, holding signs, and celebrating love and diversity.Conversation session between Caroline and Melanie2023-07-15None
c6c2e6c8...Melanie and her children completed a new painting similar to a previous one on July 17, 2023.Conversation session between Caroline and Melanie2023-07-17Melanie (PERSON)
7d94d815...Caroline shared a painting intended for her upcoming art show with Melanie on July 17, 2023.Conversation session between Caroline and Melanie2023-07-17Melanie (PERSON)
d56f77e7...Caroline visited an LGBTQ center prior to creating a painting that captures unity and strength, and she painted the artwork on July 17, 2023.Conversation session between Caroline and Melanie2023-07-17None
dacb9dd9...Caroline met and supported several amazing young LGBTQ individuals through her mentorship program as of July 17, 2023.Conversation session between Caroline and Melanie2023-07-17None
ee9a2cb4...As of July 17, 2023, Caroline has been mentoring a transgender teen, working with the teen to build confidence and develop positive strategies.Conversation session between Caroline and Melanie2023-07-17Caroline (ORG)
7ad904ba...Caroline joined a new LGBTQ activist group on Tuesday, July 18, 2023.Conversation session between Caroline and Melanie2023-07-18LGBTQ (ORG), Caroline (ORG)
de74583a...Melanie's family visits the beach only once or twice a year.Conversation session between Caroline and Melanie2023-07-20Melanie (PERSON)
2ad708a1...The activist group Caroline joined is called 'Connected LGBTQ Activists'.Conversation session between Caroline and Melanie2023-07-20Caroline (ORG)
e459c304...Caroline is meeting many cool people who are passionate about LGBTQ rights and community support.Conversation session between Caroline and Melanie2023-07-20None
1c7af606...Caroline is giving her voice to the LGBTQ activist group and believes she is making a real difference.Conversation session between Caroline and Melanie2023-07-20LGBTQ (ORG), Caroline (ORG)
c79908fa...Connected LGBTQ Activists holds regular meetings and plans events and campaigns to support each other.Conversation session between Caroline and Melanie2023-07-20None
b694e877...Melanie and her family went to the beach recently, and the kids had a blast.Conversation session between Caroline and Melanie2023-07-20Melanie (PERSON)
505f1b18...Melanie's youngest child took her first steps, and Melanie observed her wobbling and felt grateful for the milestone.Conversation session between Caroline and Melanie2023-07-20Melanie (PERSON)
da0ac683...During their family camping trips, they roast marshmallows, tell stories around the campfire, and enjoy each other's company.Conversation session between Caroline and Melanie2023-07-20None
d52aca8d...Melanie's family has an annual summer camping trip that they look forward to.Conversation session between Caroline and Melanie2023-07-20Melanie (PERSON)
ecc80873...Caroline plans to hold an LGBTQ art show featuring her paintings in August 2023 (scheduled for August 1, 2023).Conversation session between Caroline and Melanie2023-08-01None
f0610bb9...The crowd at the pride parade on August 11, 2023, celebrating love and acceptance, inspired Caroline to keep fighting for LGBTQ rights.Conversation session between Caroline and Melanie2023-08-11Caroline (ORG)
ed71c015...Caroline attended a pride parade on Friday, August 11, 2023, experiencing high energy, love, and feeling proud, reinforcing the importance of standing up for equality.Conversation session between Caroline and Melanie2023-08-11Caroline (ORG)
b8915b50...Melanie shared a photograph taken at her daughter's birthday concert on August 13, 2023, showing everyone having a blast.Conversation session between Caroline and Melanie2023-08-13Melanie (PERSON)
2a7a293c...Matt Patterson performed at Melanie's daughter's birthday concert on August 13, 2023, and his voice and songs were described as amazing.Conversation session between Caroline and Melanie2023-08-13Matt Patterson (PERSON), Melanie (PERSON)
a52890c5...Melanie celebrated her daughter's birthday with a concert on the evening of August 13, 2023, featuring music, joy, a warm summer breeze, and she observed her children's smiles.Conversation session between Caroline and Melanie2023-08-13Melanie (PERSON)
83732586...Caroline's artwork focuses on expressing her trans experience, aiming to tell her story and help people understand the trans community.Conversation session between Caroline and Melanie2023-08-14Caroline (ORG)
93140621...Caroline attended an advocacy event that involved love and support, which she described as a cool experience.Conversation session between Caroline and Melanie2023-08-14Caroline (PERSON)
cb96376b...Caroline uses her art to speak up for the LGBTQ+ community and promote acceptance.Conversation session between Caroline and Melanie2023-08-14Caroline (ORG)
1a82cb77...Caroline created and shared a recent painting on August 14, 2023, intended to represent inclusivity and diversity and to advocate for LGBTQ+ acceptance.Conversation session between Caroline and Melanie2023-08-14Caroline (ORG)
6cc619e0...Caroline created and shared a painting titled 'Embracing Identity' on August 14, 2023, depicting a woman symbolizing the journey of self-acceptance, comfort, and love.Conversation session between Caroline and Melanie2023-08-14Embracing Identity' (ORG), Caroline (ORG)
8fa8c4f3...Caroline uses art to explore her transition, her changing body, and to work through personal issues, fostering self-acceptance of imperfections.Conversation session between Caroline and Melanie2023-08-14Caroline (ORG)
80875628...While painting her self-portrait last week, Caroline felt liberated and empowered, describing the activity as therapeutic.Conversation session between Caroline and Melanie2023-08-16Caroline (ORG)
a6aa1de2...Caroline created a self-portrait last week and shared a picture of it.Conversation session between Caroline and Melanie2023-08-16Caroline (ORG)
ddf7391b...Melanie uses painting of pottery as a means of self‑expression, creating bowls with colors and patterns to make people smile.Conversation session between Caroline and Melanie2023-08-17Melanie (PERSON)
3508cee4...Caroline expressed excitement and said she can't wait for the trip, looking forward to making awesome memories.Conversation session between Caroline and Melanie2023-08-17None
c6250e4a...Melanie agreed to plan something special for the summer.Conversation session between Caroline and Melanie2023-08-17Melanie (PERSON)
50387efe...Melanie shared a picture of her finished pottery bowl with Caroline.Conversation session between Caroline and Melanie2023-08-17Melanie (PERSON), Caroline (GPE)
789ced0e...Melanie finished another pottery project.Conversation session between Caroline and Melanie2023-08-17Melanie (PERSON)
34e4bc74...Caroline suggested planning a special summer outing for just the two of them to explore nature and create memories.Conversation session between Caroline and Melanie2023-08-17Caroline (ORG)
1e23d3ab...Caroline experienced a not-so-great hike where she encountered a group of religious conservatives who said something that upset her, leading her to reflect on the need for more LGBTQ rights work.Conversation session between Caroline and Melanie2023-08-17Caroline (ORG)
71d52532...Melanie proposed that they do a family outing this summer.Conversation session between Caroline and Melanie2023-08-17Melanie (PERSON)
c1abdc5d...Melanie feels a strong connection to art, describing it as a sanctuary and source of comfort that provides her happiness and fulfillment.Conversation session between Caroline and Melanie2023-08-17Melanie (PERSON)
ea2fceb6...Melanie said she would start thinking about possible activities for their upcoming trip.Conversation session between Caroline and Melanie2023-08-17Melanie (PERSON)
c9e6db85...Caroline attempted to apologize to the people she encountered during the hiking incident on 2023-08-18.Conversation session between Caroline and Melanie2023-08-18None
0fb603e2...Caroline went hiking on 2023-08-18 and got into a bad spot with some people, after which she tried to apologize to them.Conversation session between Caroline and Melanie2023-08-18None
a4b30f95...Caroline visited a beach on 2023-08-18, watched the sun dip below the horizon, and felt the experience was amazing and calming, which later inspired her sunset painting.Conversation session between Caroline and Melanie2023-08-18Caroline (ORG)
d3c8b174...During the camping trip on 2023-08-23, Melanie and the kids roasted marshmallows and shared stories around the campfire.Conversation session between Caroline and Melanie2023-08-23Melanie (PERSON)
f279b6c9...Melanie went camping with her kids on 2023-08-23, explored the forest, hiked, and had a blast.Conversation session between Caroline and Melanie2023-08-23Melanie (PERSON)
1562d91b...Melanie shared a photo of a horse painting she created recently.Conversation session between Caroline and Melanie2023-08-23Melanie (PERSON)
bbdeb147...Melanie congratulated Caroline on taking the adoption step and expressed pride.Conversation session between Caroline and Melanie2023-08-23Caroline (PERSON), Melanie (PERSON)
21092a87...Melanie and her household acquired a cat named Bailey.Conversation session between Caroline and Melanie2023-08-23Melanie (PERSON), Bailey (PERSON)
2e1139df...Melanie shared a picture of her pet Oliver.Conversation session between Caroline and Melanie2023-08-23Melanie (PERSON), Oliver (PERSON)
62751b22...Oliver once hid his bone in Melanie's slipper.Conversation session between Caroline and Melanie2023-08-23Oliver once (PERSON), Melanie (PERSON)
ed3b9e4c...Melanie once fed a horse a carrot.Conversation session between Caroline and Melanie2023-08-23Melanie (PERSON), fed (ORG)
08c8ccc7...Caroline expressed that she feels both excited and nervous about the big responsibility of parenting.Conversation session between Caroline and Melanie2023-08-23None
4d1f4b8e...Caroline believes that art gives her a sense of freedom and that supportive people, LGBTQ rights advocacy, and living authentically are important to her.Conversation session between Caroline and Melanie2023-08-23None
0f694b9a...Melanie enjoys painting animals, finds it peaceful and special, and appreciates the grace of horses.Conversation session between Caroline and Melanie2023-08-23Melanie (PERSON)
5b3af8e4...Melanie stated that art helps people understand themselves and express their identity.Conversation session between Caroline and Melanie2023-08-23Melanie (PERSON)
ecbe1bf6...Caroline loves creating art and uses painting as a form of self-expression.Conversation session between Caroline and Melanie2023-08-23None
7afb43ba...Caroline applied to adoption agencies as her first step toward becoming a mother.Conversation session between Caroline and Melanie2023-08-23None
946ad9f3...Caroline received assistance from an adoption advice/assistance group that she attended.Conversation session between Caroline and Melanie2023-08-23Caroline (ORG)
360bd54f...Caroline owns a guinea pig named Oscar.Conversation session between Caroline and Melanie2023-08-23Caroline (ORG), Oscar (PERSON)
00251334...Caroline shared a picture of her guinea pig Oscar eating parsley, noting that vegetables are his favorite.Conversation session between Caroline and Melanie2023-08-23Oscar (PERSON)
913596c5...Caroline used to go horseback riding with her father during her childhood, riding through fields and feeling the wind.Conversation session between Caroline and Melanie2023-08-23None
d01310cd...Melanie spent the day on 2023-08-24 volunteering at a homeless shelter with her family, noting it was hard to see neglect but rewarding to make a difference.Conversation session between Caroline and Melanie2023-08-24Melanie (PERSON)
0f5465f1...Melanie made a pottery plate in a pottery class on 2023-08-24 and expressed that she loves pottery because it is relaxing and creative.Conversation session between Caroline and Melanie2023-08-24Melanie (PERSON)
2bc69802...Caroline discovered a rainbow‑colored sidewalk in her neighborhood for Pride Month, took a photograph of it on 2023-08-25, and said it felt vibrant, welcoming, and a reminder of love and acceptance.Conversation session between Caroline and Melanie2023-08-25Pride Month (EVENT)
fbf877d3...Caroline saw someone drawing on the ground on 2023-08-25, felt happy about the spontaneous art, and said such creativity can brighten someone's day.Conversation session between Caroline and Melanie2023-08-25None
dfe2d634...Caroline drew a realistic bouquet of flowers on 2023-08-25, stating that drawing flowers is one of her favorite artistic activities and that sharing nature through art brings joy.Conversation session between Caroline and Melanie2023-08-25Caroline (ORG)
75be79b3...Caroline announced that there will be a great night featuring LGBTQ artists and their talentsConversation session between Caroline and Melanie2023-08-25None
5877b6f1...Caroline said that art connects people, helps understand each other, and that she feels a sense of peace and serenity when others appreciate her work.Conversation session between Caroline and Melanie2023-08-25Caroline (ORG)
cd99e3ff...Caroline explained that the rainbow flag mural is important to her because it reflects the courage and strength of the transgender community, and that the eagle symbol on it represents freedom, pride, and her personal resilience.Conversation session between Caroline and Melanie2023-08-25Caroline (ORG)
d5273582...Caroline created a stained‑glass window for a local church on 2023-08-25, intending it to remind viewers of discovering true potential, personal growth, and her journey as a transgender woman.Conversation session between Caroline and Melanie2023-08-25Caroline (ORG)
2523c0f6...Caroline finished a vivid sunset painting on 2023-08-25, describing the colors as realistic and saying it was inspired by a beach visit the previous week.Conversation session between Caroline and Melanie2023-08-25Caroline (ORG)
e1ca15c2...Caroline and Melanie intend to organize the night to spread understanding and acceptanceConversation session between Caroline and Melanie2023-08-25Melanie (PERSON), Caroline (ORG)
5324d1cf...Melanie stated that her favorite artistic mediums are painting landscapes and still life, and she finds nature amazing.Conversation session between Caroline and Melanie2023-08-25Melanie (PERSON)
f94c2a08...Melanie expressed that she loves pottery because it is relaxing and creative, and she enjoys making functional art such as plates.Conversation session between Caroline and Melanie2023-08-25Melanie (PERSON)
8ab6ac8b...Melanie said she is feeling inspired by autumn and is planning to create several new paintings in the near future.Conversation session between Caroline and Melanie2023-08-25Melanie (PERSON)
47bfc3df...Caroline transitioned and joined the transgender community, stating that finding a supportive community where she is accepted, loved, and understood has made a huge difference in her life.Conversation session between Caroline and Melanie2023-08-25None
bbe0dfe4...Melanie painted a landscape still‑life artwork on 2023-08-25, describing it as recent and expressing that painting landscapes and still life are her favorite art forms.Conversation session between Caroline and Melanie2023-08-25Melanie (PERSON)
fb8d3c5e...Caroline told Melanie that she is stoked about an upcoming eventConversation session between Caroline and Melanie2023-08-25Melanie (PERSON), Caroline (PERSON)
b317b1db...Melanie said she appreciates Caroline's help and motivation, indicating a supportive friendship between them.Conversation session between Caroline and Melanie2023-08-25Caroline (PERSON), Melanie (PERSON)
ea614f98...Melanie took her two children to a park on 2023-08-27, where they explored, played, and enjoyed the outdoors.Conversation session between Caroline and Melanie2023-08-27Melanie (PERSON)
e11b5225...Caroline believes that playing and singing music helps her express herself, provides cathartic and uplifting experiences, and brings people together.Conversation session between Caroline and Melanie2023-08-28None
4cf2f23b...On 2023-08-28, Caroline shared her personal story with the young people at the LGBTQ+ youth center to let them know they are not alone.Conversation session between Caroline and Melanie2023-08-28Caroline (ORG)
66471609...Melanie enjoys both classical music by Bach and Mozart and modern pop music such as Ed Sheeran's 'Perfect'.Conversation session between Caroline and Melanie2023-08-28Ed Sheeran's (PERSON), Mozart (PERSON), Bach (PERSON), Melanie (PERSON)
24679343...Melanie plays the clarinet, having started when she was young, and continues to use it as a form of self‑expression and relaxation.Conversation session between Caroline and Melanie2023-08-28Melanie (PERSON)
a75828a3...Melanie attended a live music concert featuring the band 'Summer Sounds' on 2023-08-28, took a picture, and felt the event was fun and demonstrated how music brings people together.Conversation session between Caroline and Melanie2023-08-28Melanie (PERSON)
23eda9e3...On 2023-08-28, Caroline and the youth center staff began planning a talent show for the children, scheduled to take place next month.Conversation session between Caroline and Melanie2023-08-28Caroline (PERSON)
b83914aa...Caroline volunteered at an LGBTQ+ youth center on 2023-08-28, speaking with young people, finding the experience gratifying, and emphasizing the importance of kindness and support.Conversation session between Caroline and Melanie2023-08-28None
f1073015...During her volunteer shift on 2023-08-28, Caroline felt fulfilled while guiding and supporting the young attendees at the LGBTQ+ youth center.Conversation session between Caroline and Melanie2023-08-28Caroline (ORG)
c9db6620...Caroline considers the song 'Brave' by Sara Bareilles deeply meaningful because it represents courage, fighting for what is right, and reminds her of her personal progress.Conversation session between Caroline and Melanie2023-08-28Sara Bareilles (PERSON)
3ffc3212...Caroline went biking with the gang on the weekend of 2023-09-09, saw some cool sights, and sent a stunning picture of the outing.Conversation session between Caroline and Melanie2023-09-09None
1ae3209b...Melanie also spent time at a park on the weekend of 2023-09-09 and enjoyed the experience, as noted by Caroline.Conversation session between Caroline and Melanie2023-09-09Melanie (PERSON), Caroline (ORG)
1bbcfdfd...Melanie had a good time at a café on the weekend of 2023-09-09, where the café displayed thoughtful precautionary signs.Conversation session between Caroline and Melanie2023-09-09Melanie (PERSON)
88179735...Caroline is inspired by her volunteer work that benefits the LGBTQ+ community, which she says helps create a more loving world and motivates her to keep making art.Conversation session between Caroline and Melanie2023-09-13Caroline (ORG)
6801c9f8...Caroline uses painting and drawing to express her feelings and explore her gender identity; creating art was important during her transition, helping her understand and accept herself.Conversation session between Caroline and Melanie2023-09-13Caroline (ORG)
f618308e...Melanie has been practicing art for seven years, focusing on painting and pottery, and she shared a picture of her pottery creation on this date.Conversation session between Caroline and Melanie2023-09-13Melanie (PERSON)
e43f77cb...Caroline created a painting that represents her journey as a trans woman, using red and blue colors to symbolize and challenge the binary gender system, and she feels proud of her authentic self.Conversation session between Caroline and Melanie2023-09-13Caroline (ORG)
b6428a56...Caroline has not yet tried pottery but is interested in trying it in the future, and she shared a piece of artwork (a painting) she made on this date.Conversation session between Caroline and Melanie2023-09-13Caroline (ORG)
5970822b...Caroline has been creating art since she was about 17 years old.Conversation session between Caroline and Melanie2023-09-13Caroline (ORG)
277ed805...Melanie got hurt and had to take a break from pottery, which she uses for self‑expression and peace.Conversation session between Caroline and Melanie2023-09-13Melanie (PERSON)
2db31de3...Caroline is organizing an LGBTQ art show scheduled for September 2023, during which she plans to exhibit her paintings and provide a platform for the LGBTQ community.Conversation session between Caroline and Melanie2023-09-25Caroline (ORG)
013a1148...Caroline attended a transgender poetry reading last Friday, where transgender people shared their stories through poetry in a safe, empowering environment.Conversation session between Caroline and Melanie2023-10-06Caroline (ORG)
62906a7f...Caroline described the poetry reading venue as having electric energy, a supportive atmosphere, and prideful posters.Conversation session between Caroline and Melanie2023-10-06None
b9f441cf...Melanie shared a painting she created last week, inspired by sunsets, with calming colors.Conversation session between Caroline and Melanie2023-10-06Melanie (PERSON)
eb4b2697...Melanie thanked Caroline for the adoption advice.Conversation session between Caroline and Melanie2023-10-13Melanie (PERSON), Caroline (PERSON)
b8849ebd...Caroline was inspired by the poetry reading posters to create her own artwork.Conversation session between Caroline and Melanie2023-10-13Caroline (PERSON)
59ca2a4a...Caroline has been trying abstract painting recently as a form of self‑expression.Conversation session between Caroline and Melanie2023-10-13Caroline (ORG)
f2076461...Melanie has been reading a book that Caroline recommended and is painting to keep busy.Conversation session between Caroline and Melanie2023-10-13Melanie (PERSON), Caroline (PERSON)
e0723587...Caroline expressed excitement about starting a new chapter of adoption.Conversation session between Caroline and Melanie2023-10-13Caroline (ORG)
89b38d66...Melanie said she might consider adoption after hearing about her friend's successful adoption.Conversation session between Caroline and Melanie2023-10-13Melanie (PERSON)
f21ee8dc...Caroline advised Melanie to research adoption agencies or lawyers, gather references, financial information, medical checks, and prepare emotionally.Conversation session between Caroline and Melanie2023-10-13Melanie (PERSON)
e0ca9b41...Caroline offered to help Melanie with adoption in any way she can.Conversation session between Caroline and Melanie2023-10-13Melanie (PERSON)
e54b687e...Melanie created an abstract painting and shared it.Conversation session between Caroline and Melanie2023-10-13Melanie (PERSON)
800228cd...Caroline expressed that she is ready to become a mother, adopt children, and share her love and family.Conversation session between Caroline and Melanie2023-10-13None
00f7e651...Caroline drew a poster that stands for freedom and being real, representing authenticity and embracing womanhood.Conversation session between Caroline and Melanie2023-10-13Caroline (ORG)
3fd5d6f4...Melanie is doing research on adoption agencies or lawyers and is preparing emotionally for the adoption process.Conversation session between Caroline and Melanie2023-10-13Melanie (PERSON)
82019d6f...Caroline contacted her mentor for adoption advice.Conversation session between Caroline and Melanie2023-10-13Caroline (ORG)
283d5db9...During the roadtrip on October 14, 2023, Melanie's son was involved in a vehicle accident.Conversation session between Caroline and Melanie2023-10-14Melanie (PERSON)
bb043c17...After the accident on October 14, 2023, Melanie reassured her children and explained that their brother would be okay.Conversation session between Caroline and Melanie2023-10-14Melanie (PERSON)
245fb9dc...During the roadtrip on October 14, 2023, Melanie's family visited the Grand Canyon and they enjoyed it a lot.Conversation session between Caroline and Melanie2023-10-14Melanie (PERSON), the Grand Canyon (LOC)
624be110...Melanie felt scared during the accident on October 14, 2023.Conversation session between Caroline and Melanie2023-10-14Melanie (PERSON)
f35d6849...Melanie's son emerged unharmed from the accident on October 14, 2023.Conversation session between Caroline and Melanie2023-10-14Melanie (PERSON)
94cae064...Melanie, her husband, and their children went on a roadtrip during the weekend of October 14, 2023, which Melanie described as insane.Conversation session between Caroline and Melanie2023-10-14Melanie (PERSON)
5b6b5119...On October 19, 2023, Melanie and her family went on a nature/camping outing that served as relaxation after the road trip, and the children loved it.Conversation session between Caroline and Melanie2023-10-19Melanie (PERSON)
9b4fc931...On October 19, 2023, Melanie shared a photo taken that day showing her family enjoying the nature outing.Conversation session between Caroline and Melanie2023-10-19Melanie (PERSON)
241487fb...Caroline passed the adoption agency interviews on Friday, 2023-10-20.Conversation session between Caroline and Melanie2023-10-20None
ab7656e3...Caroline felt excited and thankful after passing the adoption agency interviews.Conversation session between Caroline and Melanie2023-10-20None
a69aaf0e...Melanie expressed that her family means the world to her and she is very thankful for them.Conversation session between Caroline and Melanie2023-10-20Melanie (PERSON)
400b8b2c...Caroline expressed empathy for Melanie's accident and emphasized the importance of loved ones.Conversation session between Caroline and Melanie2023-10-20Melanie (PERSON)
21e3595d...Melanie said waking up to the sound of birds and the smell of fresh air during camping always refreshes her soul.Conversation session between Caroline and Melanie2023-10-20Melanie (PERSON)
118d54b1...Melanie described camping as a chance to be present together, bonding over stories, campfires, and nature.Conversation session between Caroline and Melanie2023-10-20Melanie (PERSON)
4a332d06...Melanie said nature helps her reset and recharge, and she loves camping trips with her family because nature brings peace and serenity.Conversation session between Caroline and Melanie2023-10-20Melanie (PERSON)
2abe9529...Melanie stated that her children are resilient and give her strength to keep going.Conversation session between Caroline and Melanie2023-10-20Melanie (PERSON)
5892f19e...Melanie reflected that the accident reminded her that life is precious and she should cherish her family.Conversation session between Caroline and Melanie2023-10-20Melanie (PERSON)
e992572e...Caroline noted that family is priceless and wished Melanie luck.Conversation session between Caroline and Melanie2023-10-20Caroline (PERSON), Melanie (PERSON)
757e0d5e...Melanie bought figurines on 2023-10-21 that remind her of family love.Conversation session between Caroline and Melanie2023-10-21Melanie (PERSON)
6a7a8078...Melanie felt happy for Caroline after hearing about the interview success.Conversation session between Caroline and Melanie2023-10-21Melanie (PERSON), Caroline (PERSON)
5361b9b9...Caroline stated that she views adoption as a way of giving back, showing love and acceptance.Conversation session between Caroline and Melanie2023-10-22Caroline (PERSON)
611101ba...Melanie and Caroline affirmed that they can always be there for each other.Conversation session between Caroline and Melanie2023-10-22Caroline (PERSON), Melanie (PERSON)
8e968a37...Caroline reported receiving invaluable help and encouragement from friends, family, and people she looked up to during her transition and acceptance journey.Conversation session between Caroline and Melanie2023-10-22None
4be89858...Melanie provided emotional support to Caroline, which Caroline acknowledged as meaningful.Conversation session between Caroline and Melanie2023-10-22Caroline (ORG), Melanie (PERSON), Caroline (ORG)
4d33e29c...Caroline described her dream of creating a safe and loving home for needy kids.Conversation session between Caroline and Melanie2023-10-22None
cd93fc14...Caroline said she has found self‑acceptance after a long process and now feels ready to offer love and support to those who need it.Conversation session between Caroline and Melanie2023-10-22Caroline (ORG)
4808b89b...Caroline expressed her hope to build her own family and provide a roof over children who have not had one before.Conversation session between Caroline and Melanie2023-10-22Caroline (PERSON)
4ce55f6d...Caroline expressed appreciation for the encouragement of close friends and family, stating it shaped who she is.Conversation session between Caroline and Melanie2023-10-22None
-
- - Light Blue - 1 entity -
-
- - Dark Blue - 2+ entities -
-
- -
- Tip: Hover over nodes/edges for details
- Controls: Drag to move, scroll to zoom
- -
- - -
-
- - + - - - - \ No newline at end of file + +