bot-knows 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. bot_knows/__init__.py +70 -0
  2. bot_knows/config.py +115 -0
  3. bot_knows/domain/__init__.py +5 -0
  4. bot_knows/domain/chat.py +62 -0
  5. bot_knows/domain/message.py +64 -0
  6. bot_knows/domain/relation.py +56 -0
  7. bot_knows/domain/topic.py +132 -0
  8. bot_knows/domain/topic_evidence.py +55 -0
  9. bot_knows/importers/__init__.py +12 -0
  10. bot_knows/importers/base.py +116 -0
  11. bot_knows/importers/chatgpt.py +154 -0
  12. bot_knows/importers/claude.py +172 -0
  13. bot_knows/importers/generic_json.py +272 -0
  14. bot_knows/importers/registry.py +125 -0
  15. bot_knows/infra/__init__.py +5 -0
  16. bot_knows/infra/llm/__init__.py +6 -0
  17. bot_knows/infra/llm/anthropic_provider.py +172 -0
  18. bot_knows/infra/llm/openai_provider.py +195 -0
  19. bot_knows/infra/mongo/__init__.py +5 -0
  20. bot_knows/infra/mongo/client.py +145 -0
  21. bot_knows/infra/mongo/repositories.py +348 -0
  22. bot_knows/infra/neo4j/__init__.py +5 -0
  23. bot_knows/infra/neo4j/client.py +152 -0
  24. bot_knows/infra/neo4j/graph_repository.py +329 -0
  25. bot_knows/infra/redis/__init__.py +6 -0
  26. bot_knows/infra/redis/cache.py +198 -0
  27. bot_knows/infra/redis/client.py +193 -0
  28. bot_knows/interfaces/__init__.py +18 -0
  29. bot_knows/interfaces/embedding.py +55 -0
  30. bot_knows/interfaces/graph.py +194 -0
  31. bot_knows/interfaces/llm.py +70 -0
  32. bot_knows/interfaces/recall.py +92 -0
  33. bot_knows/interfaces/storage.py +225 -0
  34. bot_knows/logging.py +101 -0
  35. bot_knows/models/__init__.py +22 -0
  36. bot_knows/models/chat.py +55 -0
  37. bot_knows/models/ingest.py +70 -0
  38. bot_knows/models/message.py +49 -0
  39. bot_knows/models/recall.py +58 -0
  40. bot_knows/models/topic.py +100 -0
  41. bot_knows/orchestrator.py +398 -0
  42. bot_knows/py.typed +0 -0
  43. bot_knows/services/__init__.py +24 -0
  44. bot_knows/services/chat_processing.py +182 -0
  45. bot_knows/services/dedup_service.py +161 -0
  46. bot_knows/services/graph_service.py +217 -0
  47. bot_knows/services/message_builder.py +135 -0
  48. bot_knows/services/recall_service.py +296 -0
  49. bot_knows/services/tasks.py +128 -0
  50. bot_knows/services/topic_extraction.py +199 -0
  51. bot_knows/utils/__init__.py +22 -0
  52. bot_knows/utils/hashing.py +126 -0
  53. bot_knows-0.1.0.dist-info/METADATA +294 -0
  54. bot_knows-0.1.0.dist-info/RECORD +56 -0
  55. bot_knows-0.1.0.dist-info/WHEEL +4 -0
  56. bot_knows-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,126 @@
1
+ """Hashing utilities for bot_knows.
2
+
3
+ This module provides deterministic hash functions for generating
4
+ stable identifiers for chats, messages, topics, and evidence.
5
+ """
6
+
7
+ import hashlib
8
+ from typing import Any
9
+
10
+ __all__ = [
11
+ "generate_chat_id",
12
+ "generate_evidence_id",
13
+ "generate_message_id",
14
+ "generate_topic_id",
15
+ "hash_text",
16
+ ]
17
+
18
+
19
+ def hash_text(text: str) -> str:
20
+ """Generate SHA256 hash of text.
21
+
22
+ Args:
23
+ text: Input text to hash
24
+
25
+ Returns:
26
+ Hexadecimal SHA256 hash string
27
+ """
28
+ return hashlib.sha256(text.encode("utf-8")).hexdigest()
29
+
30
+
31
+ def generate_chat_id(title: str, source: str, timestamp: int) -> str:
32
+ """Generate deterministic chat ID.
33
+
34
+ The chat ID is a SHA256 hash of: title + source + timestamp.
35
+ This ensures the same chat imported multiple times gets the same ID.
36
+
37
+ Args:
38
+ title: Chat title
39
+ source: Import source (e.g., "chatgpt", "claude")
40
+ timestamp: Chat creation timestamp (epoch seconds)
41
+
42
+ Returns:
43
+ Hexadecimal SHA256 hash string
44
+ """
45
+ combined = f"{title}|{source}|{timestamp}"
46
+ return hash_text(combined)
47
+
48
+
49
+ def generate_message_id(
50
+ chat_id: str,
51
+ user_content: str,
52
+ assistant_content: str,
53
+ timestamp: int,
54
+ ) -> str:
55
+ """Generate deterministic message ID.
56
+
57
+ The message ID is based on chat_id + content + timestamp to ensure
58
+ uniqueness within a chat while being deterministic.
59
+
60
+ Args:
61
+ chat_id: Parent chat ID
62
+ user_content: User message content
63
+ assistant_content: Assistant response content
64
+ timestamp: Message timestamp (epoch seconds)
65
+
66
+ Returns:
67
+ Hexadecimal SHA256 hash string
68
+ """
69
+ combined = f"{chat_id}|{user_content}|{assistant_content}|{timestamp}"
70
+ return hash_text(combined)
71
+
72
+
73
+ def generate_topic_id(canonical_name: str, source_message_id: str) -> str:
74
+ """Generate deterministic topic ID.
75
+
76
+ The topic ID combines the canonical name with the first message
77
+ that introduced it, ensuring uniqueness.
78
+
79
+ Args:
80
+ canonical_name: Canonical topic name
81
+ source_message_id: ID of the message that first introduced this topic
82
+
83
+ Returns:
84
+ Hexadecimal SHA256 hash string
85
+ """
86
+ combined = f"topic|{canonical_name}|{source_message_id}"
87
+ return hash_text(combined)
88
+
89
+
90
+ def generate_evidence_id(
91
+ topic_id: str,
92
+ extracted_name: str,
93
+ source_message_id: str,
94
+ timestamp: int,
95
+ ) -> str:
96
+ """Generate deterministic evidence ID.
97
+
98
+ Evidence IDs are unique per extraction event.
99
+
100
+ Args:
101
+ topic_id: Parent topic ID
102
+ extracted_name: Raw extracted topic name
103
+ source_message_id: Source message ID
104
+ timestamp: Extraction timestamp (epoch seconds)
105
+
106
+ Returns:
107
+ Hexadecimal SHA256 hash string
108
+ """
109
+ combined = f"evidence|{topic_id}|{extracted_name}|{source_message_id}|{timestamp}"
110
+ return hash_text(combined)
111
+
112
+
113
+ def stable_hash(*args: Any) -> str:
114
+ """Generate a stable hash from multiple arguments.
115
+
116
+ Converts all arguments to strings and joins them with pipe separator.
117
+ Useful for creating composite keys.
118
+
119
+ Args:
120
+ *args: Values to include in the hash
121
+
122
+ Returns:
123
+ Hexadecimal SHA256 hash string
124
+ """
125
+ combined = "|".join(str(arg) for arg in args)
126
+ return hash_text(combined)
@@ -0,0 +1,294 @@
1
+ Metadata-Version: 2.4
2
+ Name: bot-knows
3
+ Version: 0.1.0
4
+ Summary: Framework-agnostic Python library for graph-backed personal knowledge bases from chat data
5
+ Project-URL: Homepage, https://github.com/Snezhana/bot-knows
6
+ Project-URL: Documentation, https://github.com/Snezhana/bot-knows#readme
7
+ Project-URL: Repository, https://github.com/Snezhana/bot-knows
8
+ Project-URL: Issues, https://github.com/Snezhana/bot-knows/issues
9
+ Author-email: Your Name <your@email.com>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: chat,embedding,graph,knowledge-base,memory,nlp,recall
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Framework :: AsyncIO
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Programming Language :: Python :: 3.14
19
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
20
+ Classifier: Typing :: Typed
21
+ Requires-Python: >=3.13
22
+ Requires-Dist: anthropic<1.0,>=0.42
23
+ Requires-Dist: anyio<5.0,>=4.7
24
+ Requires-Dist: motor<4.0,>=3.6
25
+ Requires-Dist: neo4j<6.0,>=5.27
26
+ Requires-Dist: numpy<3.0,>=2.2
27
+ Requires-Dist: openai<2.0,>=1.59
28
+ Requires-Dist: pydantic-settings<3.0,>=2.6
29
+ Requires-Dist: pydantic<3.0,>=2.10
30
+ Requires-Dist: redis<6.0,>=5.2
31
+ Requires-Dist: structlog<26.0,>=25.1
32
+ Requires-Dist: taskiq-redis<2.0,>=1.0
33
+ Requires-Dist: taskiq<1.0,>=0.11
34
+ Provides-Extra: dev
35
+ Requires-Dist: hypothesis<7.0,>=6.100; extra == 'dev'
36
+ Requires-Dist: mongomock-motor>=0.0.32; extra == 'dev'
37
+ Requires-Dist: mypy<2.0,>=1.14; extra == 'dev'
38
+ Requires-Dist: pre-commit<5.0,>=4.0; extra == 'dev'
39
+ Requires-Dist: pytest-asyncio<1.0,>=0.25; extra == 'dev'
40
+ Requires-Dist: pytest-cov<7.0,>=6.0; extra == 'dev'
41
+ Requires-Dist: pytest<9.0,>=8.3; extra == 'dev'
42
+ Requires-Dist: ruff<1.0,>=0.9; extra == 'dev'
43
+ Description-Content-Type: text/markdown
44
+
45
+ # bot-knows
46
+
47
+ A framework-agnostic Python library for building graph-backed personal knowledge bases from chat data.
48
+
49
+ ## Features
50
+
51
+ - **Multi-source Chat Ingestion**: Import chats from ChatGPT, Claude, and custom JSON formats
52
+ - **Semantic Topic Extraction**: LLM-powered topic extraction with confidence scores
53
+ - **Intelligent Deduplication**: Embedding-based semantic deduplication with configurable thresholds
54
+ - **Graph-backed Knowledge Base**: Neo4j-powered relationship graph for topics and messages
55
+ - **Evidence-weighted Recall**: Spaced repetition-inspired recall system with decay and reinforcement
56
+ - **Pluggable Infrastructure**: Bring your own storage, graph database, or LLM provider
57
+
58
+ ## Requirements
59
+
60
+ - Python >= 3.13
61
+ - MongoDB (storage) - or custom storage implementation
62
+ - Neo4j (graph database) - or custom graph implementation
63
+ - Redis (optional, for caching)
64
+ - OpenAI or Anthropic API key (for LLM features) - or custom LLM implementation
65
+
66
+ ## Installation
67
+
68
+ ```bash
69
+ pip install bot-knows
70
+ ```
71
+
72
+ Or with uv:
73
+
74
+ ```bash
75
+ uv add bot-knows
76
+ ```
77
+
78
+ ## Quick Start
79
+
80
+ The `BotKnows` class is the main orchestrator that accepts implementation classes for storage, graph database, and LLM providers. Configuration is automatically loaded from environment variables.
81
+
82
+ ### Using Built-in Infrastructure
83
+
84
+ ```python
85
+ from bot_knows import (
86
+ BotKnows,
87
+ MongoStorageRepository,
88
+ Neo4jGraphRepository,
89
+ OpenAIProvider,
90
+ ChatGPTAdapter,
91
+ )
92
+
93
+ async def main():
94
+ # Config is loaded from .env automatically
95
+ async with BotKnows(
96
+ storage_class=MongoStorageRepository,
97
+ graphdb_class=Neo4jGraphRepository,
98
+ llm_class=OpenAIProvider,
99
+ ) as bk:
100
+ # Import ChatGPT conversations
101
+ result = await bk.insert_chats("conversations.json", ChatGPTAdapter)
102
+ print(f"Imported {result.chats_new} chats, {result.topics_created} topics")
103
+
104
+ # Query the knowledge base
105
+ topics = await bk.get_chat_topics(chat_id)
106
+ due_topics = await bk.get_due_topics(threshold=0.3)
107
+ ```
108
+
109
+ ### Available Implementations
110
+
111
+ **Storage:**
112
+ - `MongoStorageRepository` - MongoDB-based storage
113
+
114
+ **Graph Database:**
115
+ - `Neo4jGraphRepository` - Neo4j graph database
116
+
117
+ **LLM Providers:**
118
+ - `OpenAIProvider` - OpenAI API (GPT models + embeddings)
119
+ - `AnthropicProvider` - Anthropic API (Claude models)
120
+
121
+ **Import Adapters:**
122
+ - `ChatGPTAdapter` - ChatGPT export format
123
+ - `ClaudeAdapter` - Claude export format
124
+ - `GenericJSONAdapter` - Custom JSON format
125
+
126
+
127
+ ## Custom Implementations
128
+
129
+ You can provide your own implementations by implementing the required interfaces. Set `config_class = None` on your class and pass configuration via the `*_custom_config` parameters.
130
+
131
+ ### Interfaces
132
+
133
+ - `StorageInterface` - Persistent storage for chats, messages, topics, evidence, and recall state
134
+ - `GraphServiceInterface` - Graph database operations for the knowledge graph
135
+ - `LLMInterface` - LLM interactions for classification and topic extraction
136
+ - `EmbeddingServiceInterface` - Text embedding generation
137
+
138
+ ### Example: Custom Storage Implementation
139
+
140
+ ```python
141
+ from bot_knows import BotKnows, StorageInterface, Neo4jGraphRepository, OpenAIProvider
142
+
143
+ class MyCustomStorage:
144
+ """Custom storage implementation."""
145
+
146
+ config_class = None # Signals custom config
147
+
148
+ @classmethod
149
+ async def from_dict(cls, config: dict) -> "MyCustomStorage":
150
+ """Factory method for custom config."""
151
+ return cls(connection_string=config["connection_string"])
152
+
153
+ def __init__(self, connection_string: str):
154
+ self.conn = connection_string
155
+
156
+ # Implement all StorageInterface methods...
157
+ async def save_chat(self, chat): ...
158
+ async def get_chat(self, chat_id): ...
159
+ # ... etc
160
+
161
+ async with BotKnows(
162
+ storage_class=MyCustomStorage,
163
+ graphdb_class=Neo4jGraphRepository,
164
+ llm_class=OpenAIProvider,
165
+ storage_custom_config={"connection_string": "postgresql://..."},
166
+ ) as bk:
167
+ result = await bk.insert_chats("data.json", ChatGPTAdapter)
168
+ ```
169
+
170
+ ### Example: Custom LLM Provider
171
+
172
+ ```python
173
+ from bot_knows import BotKnows, LLMInterface, MongoStorageRepository, Neo4jGraphRepository
174
+
175
+ class MyLLMProvider:
176
+ """Custom LLM provider (e.g., local model, different API)."""
177
+
178
+ config_class = None
179
+
180
+ @classmethod
181
+ async def from_dict(cls, config: dict) -> "MyLLMProvider":
182
+ return cls(api_url=config["api_url"], model=config["model"])
183
+
184
+ def __init__(self, api_url: str, model: str):
185
+ self.api_url = api_url
186
+ self.model = model
187
+
188
+ # Implement LLMInterface methods
189
+ async def classify_chat(self, first_pair, last_pair): ...
190
+ async def extract_topics(self, user_content, assistant_content): ...
191
+ async def normalize_topic_name(self, name): ...
192
+
193
+ # Implement EmbeddingServiceInterface if used as embedding provider
194
+ async def embed(self, texts): ...
195
+
196
+ async with BotKnows(
197
+ storage_class=MongoStorageRepository,
198
+ graphdb_class=Neo4jGraphRepository,
199
+ llm_class=MyLLMProvider,
200
+ llm_custom_config={"api_url": "http://localhost:8000", "model": "llama3"},
201
+ ) as bk:
202
+ result = await bk.insert_chats("data.json", ChatGPTAdapter)
203
+ ```
204
+
205
+ ## Configuration
206
+
207
+ Configuration is loaded from environment variables. See `.env.example` for all available options.
208
+
209
+ Key environment variables:
210
+ - `MONGODB_URI` - MongoDB connection string
211
+ - `NEO4J_URI`, `NEO4J_USER`, `NEO4J_PASSWORD` - Neo4j connection
212
+ - `OPENAI_API_KEY` - OpenAI API key
213
+ - `ANTHROPIC_API_KEY` - Anthropic API key
214
+ - `DEDUP_HIGH_THRESHOLD`, `DEDUP_LOW_THRESHOLD` - Deduplication thresholds
215
+
216
+ ## Architecture
217
+
218
+ ```
219
+ Input Sources (ChatGPT, Claude, Custom JSON)
220
+
221
+ Import Adapters (normalize to ChatIngest)
222
+
223
+ Domain Processing
224
+ ├── Chat identity resolution
225
+ ├── One-time Chat classification
226
+ ├── Message creation & ordering
227
+
228
+ Topic Extraction
229
+ ├── LLM-based extraction
230
+ ├── Semantic deduplication
231
+ ├── Evidence append
232
+
233
+ Graph Updates (Neo4j)
234
+ ```
235
+
236
+ ## Retrieval API
237
+
238
+ ```python
239
+ async with BotKnows(...) as bk:
240
+ # Get messages for a chat
241
+ messages = await bk.get_messages_for_chat(chat_id)
242
+
243
+ # Get topics for a chat
244
+ topic_ids = await bk.get_chat_topics(chat_id)
245
+
246
+ # Get related topics
247
+ related = await bk.get_related_topics(topic_id, limit=10)
248
+
249
+ # Get topic evidence
250
+ evidence = await bk.get_topic_evidence(topic_id)
251
+
252
+ # Spaced repetition recall
253
+ recall_state = await bk.get_recall_state(topic_id)
254
+ due_topics = await bk.get_due_topics(threshold=0.3)
255
+ all_states = await bk.get_all_recall_states()
256
+ ```
257
+
258
+ ## Development
259
+
260
+ ```bash
261
+ # Install with dev dependencies
262
+ uv sync --dev
263
+
264
+ # Run tests
265
+ uv run pytest
266
+
267
+ # Type checking
268
+ uv run mypy src/
269
+
270
+ # Linting
271
+ uv run ruff check src/
272
+ ```
273
+
274
+ ## Future Plans
275
+
276
+ The built-in infrastructure will be extended with additional providers:
277
+
278
+ - **Storage**: PostgreSQL, SQLite
279
+ - **Graph**: Amazon Neptune, TigerGraph, MemGraph
280
+ - **LLM**: Google Gemini, Ollama, HuggingFace
281
+
282
+ ## Contributing
283
+
284
+ Contributions are welcome! If you'd like to add a new infrastructure implementation:
285
+
286
+ 1. Implement the appropriate interface (`StorageInterface`, `GraphServiceInterface`, `LLMInterface`, or `EmbeddingServiceInterface`)
287
+ 2. Add a `config_class` for environment-based configuration (or set to `None` for custom config)
288
+ 3. Implement the `from_config` class method (or `from_dict` if `config_class` is `None`)
289
+ 4. Add tests for your implementation
290
+ 5. Submit a pull request
291
+
292
+ ## License
293
+
294
+ MIT
@@ -0,0 +1,56 @@
1
+ bot_knows/__init__.py,sha256=2YtzVyPMHcfBMRK-l0glSbMtnl97ppdtqVFKwdl_F-4,2246
2
+ bot_knows/config.py,sha256=1BLyyRWxloUCqkIrIWBE7iPyvbnxgoBUj3w901FpmbU,2972
3
+ bot_knows/logging.py,sha256=Hn7t7tw8dMbxzc10QNeJ8l0jllth3TUpA55PiyIbvPU,2715
4
+ bot_knows/orchestrator.py,sha256=5x93HLdCiBlWzC4TAvTeVShG5Op7v75GMCezx3M6VhE,15361
5
+ bot_knows/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ bot_knows/domain/__init__.py,sha256=3GzhgssFbe-_r8bhlQBMG2267JQrSbAAD1YtNrfHxEw,151
7
+ bot_knows/domain/chat.py,sha256=G4ajsoItoiW8usBBqub3r7UUuYoBvYknStVv3PCJO_4,1618
8
+ bot_knows/domain/message.py,sha256=a4betNQ5s-R6ZvUrrVesrCldIYpLTUvJmUn5X5aXF_Y,1793
9
+ bot_knows/domain/relation.py,sha256=z7MAK4Bf6C_MfhmBt2pq3CHWx4HmxgPW24vPD8Hm1o4,1375
10
+ bot_knows/domain/topic.py,sha256=d4Sntbk7fs1B_z6N_qr6zp_8R42KvOrHQm1cGevF1Qc,4367
11
+ bot_knows/domain/topic_evidence.py,sha256=yrDNvNdoW3pfT1k9QGfc-GJ_E4USAIhIGt1f3a2B5UA,1603
12
+ bot_knows/importers/__init__.py,sha256=5QwL3BuxgJHVz6hzTrxLEYxFwvNgywzFSYn9EVbuyoo,291
13
+ bot_knows/importers/base.py,sha256=M2HTVh3L0j5Jjj6gP72yGn1asKX4F9Lq8YJyglSotSA,3048
14
+ bot_knows/importers/chatgpt.py,sha256=YFtAaI8GgaIGPsMXBjvWAcwdUjGY3FjNzDsLEXPxKX0,4666
15
+ bot_knows/importers/claude.py,sha256=X3gjrYXdAuRUD0tCWRAbcXD6jXbX1-0o1LQQGWRN-ew,5475
16
+ bot_knows/importers/generic_json.py,sha256=UTngXdw0KTcUnzSsXINFdDWU86kW5Rh85-MQstaEhyI,8879
17
+ bot_knows/importers/registry.py,sha256=ZZRTcbSkNC1tZuZnKMWspFsdHFIZmkpvzG8JN6tk5P0,3405
18
+ bot_knows/infra/__init__.py,sha256=9vRgOa4HBmNhhYh1sC7SLInN5qZoPf7pXbb_UxdBCyI,166
19
+ bot_knows/infra/llm/__init__.py,sha256=H2EplSurbmpun-jNPznUr-KWm8JaF8fuBmDMLWHT9Uk,234
20
+ bot_knows/infra/llm/anthropic_provider.py,sha256=nOdOCc1jljrA3LZmutuNfAHpiBPlHUxAwnuymmwrY2I,5774
21
+ bot_knows/infra/llm/openai_provider.py,sha256=zBTxtdZPovR6GDPSy6QBWRqJlW2C47nwvhsnuQvniv8,6650
22
+ bot_knows/infra/mongo/__init__.py,sha256=UfYYi8N0gp9pdbzOl7guzI_VYiowZ_IuFjoPokeyciM,125
23
+ bot_knows/infra/mongo/client.py,sha256=hrLGQl5pizTgQAfB8FhLNT3YH8mf3Cjwf70sjIvcubM,4561
24
+ bot_knows/infra/mongo/repositories.py,sha256=jrmY0sBRufcOQB7BF3EIM8sZLr7_h29LMs93osx4a_s,12411
25
+ bot_knows/infra/neo4j/__init__.py,sha256=akgXC0DbbNFSFfsQ2aFewlSs-Wko8vRGFYwmbQiKtkk,123
26
+ bot_knows/infra/neo4j/client.py,sha256=x6CFmAJw_KFSUpL1E7USPpGTKUQdje7OUB0rIlvI_BI,4623
27
+ bot_knows/infra/neo4j/graph_repository.py,sha256=fFLsxMqqBoEheKN4z703SfY4ouUCAdhe4vfDIvelm9c,10936
28
+ bot_knows/infra/redis/__init__.py,sha256=P00gyYoxYYhH8c2ZwWnEginTM0uCjS9Py2KmI2avnIU,207
29
+ bot_knows/infra/redis/cache.py,sha256=ybeMuq_JKGtDn0QoWSQRff5t9pJwzRKQfzfnBUORiGY,4903
30
+ bot_knows/infra/redis/client.py,sha256=HUBXX7DQqmip2UOxloeNJOe1L5ZHXuJkEthu-z3BkSI,5456
31
+ bot_knows/interfaces/__init__.py,sha256=CHsG3hqjxatHR27az6QK7kY4_GmsWc5BiXX-cgDNKJE,572
32
+ bot_knows/interfaces/embedding.py,sha256=KzMupF3lpodBJQ8vbBKzvAHyUbnjLRH79BSTHyq79ss,1364
33
+ bot_knows/interfaces/graph.py,sha256=5YlkOGjHE4aM4Bba-hRwCMATmsXbTQuMq6QkRyR6Xck,4823
34
+ bot_knows/interfaces/llm.py,sha256=XoxkKhEPGdFjp3XcWR20_usT2WU94XRCWpQ-bzo07dk,1802
35
+ bot_knows/interfaces/recall.py,sha256=Z4D-ki1LhY5OVZfayuiW4WP6bcERBfMlXs0yiQICMPY,2485
36
+ bot_knows/interfaces/storage.py,sha256=sueoZfNiurQ-ZyZ-IJ7BrLz8ooO5YOBEnnkA8VGQDs4,5324
37
+ bot_knows/models/__init__.py,sha256=cFlEwzNHm6hBDgH7Jtswgg5U65JfxQLiYxm3-rB5C60,590
38
+ bot_knows/models/chat.py,sha256=_hWXeXuoOR7theOkT0jM5Sf_ff3MbquECPRszOUgjIg,1616
39
+ bot_knows/models/ingest.py,sha256=JO8F_s8W3rLUONqOqHD5HE6FeAqb3-F0PI1BBXkYK-c,2515
40
+ bot_knows/models/message.py,sha256=rAYMchsfv78Pig3qxEI2XXbsQLG1tq9-FT77FE4Flnw,1716
41
+ bot_knows/models/recall.py,sha256=SGdPqSwlmx5ZoG53hv6tzNQsV_NTJsgkuKcY-2E1OkQ,1973
42
+ bot_knows/models/topic.py,sha256=Ma_6ZskccovKkDVQAmlCL5WEO-dcfsmG0ID2Ag6L-rY,3637
43
+ bot_knows/services/__init__.py,sha256=y8tdc3Zjg_tFL62f8manuxIOL2xkNseSh3n9-MLujFA,766
44
+ bot_knows/services/chat_processing.py,sha256=c9K7V6F25gwSdU5fKCsVepPUIjxG4hyXycpfYTSmtIM,5579
45
+ bot_knows/services/dedup_service.py,sha256=6CXcuddHed1maVozllySUt6QV5Q078eqa-KFsaJmdQk,4892
46
+ bot_knows/services/graph_service.py,sha256=kQ8Of0B9p-eTIOTmf66VySlCQI0BmN_tmjFfNfX_hms,6251
47
+ bot_knows/services/message_builder.py,sha256=pH4JrNxh8EMUZySdkBeZMU1kAkYa67IAnOq-SMfowCs,4305
48
+ bot_knows/services/recall_service.py,sha256=3pl3dFHozhhdxHuMK09tpcnUVjkOLQ9_SwDqmRWGaeQ,9261
49
+ bot_knows/services/tasks.py,sha256=zZY1l6pqB_lRC086HxOoMabJQMbs5V7H-6En53FbNN8,3127
50
+ bot_knows/services/topic_extraction.py,sha256=StKW_DJvH3Fz2V4zSLJXkc1Fz1BJiLsE3gHuDLlZSNk,6059
51
+ bot_knows/utils/__init__.py,sha256=nVhLzC1PyrKznRLNwAIzK-ezQbMI9deSH7b2NYWaJpE,414
52
+ bot_knows/utils/hashing.py,sha256=zojSIplC6QrrEdbY7IzxPOzhadGg_JEXLMP2jKBjH6w,3301
53
+ bot_knows-0.1.0.dist-info/METADATA,sha256=VyQCTKQvp_ti7eWbJvIDxrLw8u0Riw4bUCPKdctuZ8Q,9267
54
+ bot_knows-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
55
+ bot_knows-0.1.0.dist-info/licenses/LICENSE,sha256=RHOQqM9jQr_WQ9xFYn0V0QCu3w0T4SphrB38cPmKlhQ,1096
56
+ bot_knows-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Snezhana Stojanova
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.