protoprompt 0.1.0__tar.gz

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 (80) hide show
  1. protoprompt-0.1.0/CHANGELOG.md +34 -0
  2. protoprompt-0.1.0/LICENSE +21 -0
  3. protoprompt-0.1.0/MANIFEST.in +11 -0
  4. protoprompt-0.1.0/PKG-INFO +201 -0
  5. protoprompt-0.1.0/README.en.md +164 -0
  6. protoprompt-0.1.0/README.md +163 -0
  7. protoprompt-0.1.0/docs/en/api/context.md +3 -0
  8. protoprompt-0.1.0/docs/en/api/injector.md +17 -0
  9. protoprompt-0.1.0/docs/en/api/pipeline.md +5 -0
  10. protoprompt-0.1.0/docs/en/api/profile.md +9 -0
  11. protoprompt-0.1.0/docs/en/api/session.md +17 -0
  12. protoprompt-0.1.0/docs/en/api/store.md +13 -0
  13. protoprompt-0.1.0/docs/en/api/tokens.md +13 -0
  14. protoprompt-0.1.0/docs/en/changelog.md +3 -0
  15. protoprompt-0.1.0/docs/en/concepts/budget.md +72 -0
  16. protoprompt-0.1.0/docs/en/concepts/compression.md +81 -0
  17. protoprompt-0.1.0/docs/en/concepts/context.md +44 -0
  18. protoprompt-0.1.0/docs/en/index.md +67 -0
  19. protoprompt-0.1.0/docs/en/license.md +3 -0
  20. protoprompt-0.1.0/docs/en/quickstart.md +97 -0
  21. protoprompt-0.1.0/docs/ru/api/context.md +3 -0
  22. protoprompt-0.1.0/docs/ru/api/injector.md +17 -0
  23. protoprompt-0.1.0/docs/ru/api/pipeline.md +5 -0
  24. protoprompt-0.1.0/docs/ru/api/profile.md +9 -0
  25. protoprompt-0.1.0/docs/ru/api/session.md +17 -0
  26. protoprompt-0.1.0/docs/ru/api/store.md +13 -0
  27. protoprompt-0.1.0/docs/ru/api/tokens.md +13 -0
  28. protoprompt-0.1.0/docs/ru/changelog.md +3 -0
  29. protoprompt-0.1.0/docs/ru/concepts/budget.md +70 -0
  30. protoprompt-0.1.0/docs/ru/concepts/compression.md +86 -0
  31. protoprompt-0.1.0/docs/ru/concepts/context.md +44 -0
  32. protoprompt-0.1.0/docs/ru/index.md +67 -0
  33. protoprompt-0.1.0/docs/ru/license.md +3 -0
  34. protoprompt-0.1.0/docs/ru/quickstart.md +99 -0
  35. protoprompt-0.1.0/mkdocs.en.yml +60 -0
  36. protoprompt-0.1.0/mkdocs.ru.yml +60 -0
  37. protoprompt-0.1.0/protoprompt/__init__.py +58 -0
  38. protoprompt-0.1.0/protoprompt/context.py +33 -0
  39. protoprompt-0.1.0/protoprompt/exceptions.py +20 -0
  40. protoprompt-0.1.0/protoprompt/injector.py +69 -0
  41. protoprompt-0.1.0/protoprompt/injector_budgeted.py +219 -0
  42. protoprompt-0.1.0/protoprompt/llm.py +12 -0
  43. protoprompt-0.1.0/protoprompt/pipeline.py +71 -0
  44. protoprompt-0.1.0/protoprompt/profile/__init__.py +4 -0
  45. protoprompt-0.1.0/protoprompt/profile/builder.py +62 -0
  46. protoprompt-0.1.0/protoprompt/profile/schema.py +24 -0
  47. protoprompt-0.1.0/protoprompt/profile/types.py +12 -0
  48. protoprompt-0.1.0/protoprompt/session/__init__.py +16 -0
  49. protoprompt-0.1.0/protoprompt/session/compressor.py +17 -0
  50. protoprompt-0.1.0/protoprompt/session/strategy.py +200 -0
  51. protoprompt-0.1.0/protoprompt/session/types.py +17 -0
  52. protoprompt-0.1.0/protoprompt/store/__init__.py +4 -0
  53. protoprompt-0.1.0/protoprompt/store/chroma.py +71 -0
  54. protoprompt-0.1.0/protoprompt/store/memory.py +79 -0
  55. protoprompt-0.1.0/protoprompt/store/protocol.py +39 -0
  56. protoprompt-0.1.0/protoprompt/tokens/__init__.py +7 -0
  57. protoprompt-0.1.0/protoprompt/tokens/protocol.py +25 -0
  58. protoprompt-0.1.0/protoprompt/tokens/regex_counter.py +52 -0
  59. protoprompt-0.1.0/protoprompt/tokens/tiktoken_adapter.py +57 -0
  60. protoprompt-0.1.0/protoprompt.egg-info/PKG-INFO +201 -0
  61. protoprompt-0.1.0/protoprompt.egg-info/SOURCES.txt +78 -0
  62. protoprompt-0.1.0/protoprompt.egg-info/dependency_links.txt +1 -0
  63. protoprompt-0.1.0/protoprompt.egg-info/requires.txt +14 -0
  64. protoprompt-0.1.0/protoprompt.egg-info/top_level.txt +1 -0
  65. protoprompt-0.1.0/pyproject.toml +71 -0
  66. protoprompt-0.1.0/scripts/build_docs.py +143 -0
  67. protoprompt-0.1.0/setup.cfg +4 -0
  68. protoprompt-0.1.0/tests/__init__.py +0 -0
  69. protoprompt-0.1.0/tests/_mocks.py +34 -0
  70. protoprompt-0.1.0/tests/conftest.py +27 -0
  71. protoprompt-0.1.0/tests/test_budgeted.py +148 -0
  72. protoprompt-0.1.0/tests/test_chroma_store.py +70 -0
  73. protoprompt-0.1.0/tests/test_compressor.py +62 -0
  74. protoprompt-0.1.0/tests/test_injector.py +92 -0
  75. protoprompt-0.1.0/tests/test_integration.py +86 -0
  76. protoprompt-0.1.0/tests/test_llm_strategy.py +103 -0
  77. protoprompt-0.1.0/tests/test_pipeline.py +81 -0
  78. protoprompt-0.1.0/tests/test_store.py +50 -0
  79. protoprompt-0.1.0/tests/test_store_advanced.py +48 -0
  80. protoprompt-0.1.0/tests/test_tokens.py +87 -0
@@ -0,0 +1,34 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] - 2026-07-10
9
+
10
+ ### Added
11
+ - `protoprompt.tokens` subpackage with pluggable `TokenCounter` protocol
12
+ and a regex-based default implementation. Optional `tiktoken` adapter.
13
+ - `LLMSummaryStrategy` for LLM-based session compression with
14
+ `HeuristicStrategy` fallback on failure.
15
+ - `TokenBudgetedContextBuilder` with priority-based greedy token allocation
16
+ and `BudgetReport` observability.
17
+ - Real ChromaDB integration tests gated on the `chroma` extra.
18
+ - MkDocs Material documentation under `docs/`.
19
+ - GitHub Actions CI workflow across Python 3.11-3.13.
20
+
21
+ ### Changed
22
+ - `ContextBuilder` now embeds the query once and reuses it for RAG and
23
+ session retrieval (was: embedded twice).
24
+ - `InMemStore` supports filtering on any metadata field, not only `doc_id`.
25
+ - `StoreProtocol.query` accepts an optional `score_threshold`.
26
+ - `Pipeline.compress_and_store` writes to a `_new` doc_id first, then deletes
27
+ the old one, to avoid data loss on crash between steps.
28
+ - `ProfileBuilder` logs the original exception instead of silently returning
29
+ an empty profile.
30
+ - `HeuristicStrategy` honours a `min_messages` threshold.
31
+
32
+ ### Fixed
33
+ - Public re-exports in `protoprompt.profile`, `protoprompt.session`,
34
+ `protoprompt.store` so IDEs and type checkers see the full API.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 EnergoAI Hub
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.
@@ -0,0 +1,11 @@
1
+ include README.md
2
+ include README.en.md
3
+ include README.ru.md
4
+ include LICENSE
5
+ include CHANGELOG.md
6
+ recursive-include docs *.md
7
+ recursive-include scripts *.py
8
+ recursive-include examples *.py
9
+ recursive-include tests *.py
10
+ include mkdocs.ru.yml
11
+ include mkdocs.en.yml
@@ -0,0 +1,201 @@
1
+ Metadata-Version: 2.4
2
+ Name: protoprompt
3
+ Version: 0.1.0
4
+ Summary: Layered context builder for LLM prompts: RAG + compressed session memory + user profile
5
+ Author: EnergoAI Hub
6
+ Maintainer: EnergoAI Hub
7
+ License: MIT
8
+ Project-URL: Homepage, https://github.com/Idxeed/protoprompt
9
+ Project-URL: Documentation, https://idxeed.github.io/protoprompt/
10
+ Project-URL: Source, https://github.com/Idxeed/protoprompt
11
+ Project-URL: Issues, https://github.com/Idxeed/protoprompt/issues
12
+ Project-URL: Changelog, https://github.com/Idxeed/protoprompt/blob/main/CHANGELOG.md
13
+ Keywords: llm,rag,prompt,context,embedding
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
22
+ Classifier: Typing :: Typed
23
+ Requires-Python: >=3.11
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Provides-Extra: chroma
27
+ Requires-Dist: chromadb<0.6,>=0.5; extra == "chroma"
28
+ Provides-Extra: tiktoken
29
+ Requires-Dist: tiktoken>=0.5; extra == "tiktoken"
30
+ Provides-Extra: dev
31
+ Requires-Dist: pytest>=8; extra == "dev"
32
+ Requires-Dist: pytest-asyncio>=0.24; extra == "dev"
33
+ Requires-Dist: pytest-cov>=5; extra == "dev"
34
+ Requires-Dist: mkdocs>=1.5; extra == "dev"
35
+ Requires-Dist: mkdocs-material>=9; extra == "dev"
36
+ Requires-Dist: mkdocstrings[python]>=0.24; extra == "dev"
37
+ Dynamic: license-file
38
+
39
+ # protoprompt
40
+
41
+ [![CI](https://github.com/Idxeed/protoprompt/actions/workflows/ci.yml/badge.svg)](https://github.com/Idxeed/protoprompt/actions/workflows/ci.yml)
42
+ [![Coverage](https://img.shields.io/codecov/c/github/Idxeed/protoprompt)](https://codecov.io/gh/Idxeed/protoprompt)
43
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue)](https://www.python.org/)
44
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
45
+ [![RU](https://img.shields.io/badge/%D0%AF%D0%B7%D1%8B%D0%BA-RU-blue)](README.ru.md)
46
+ [![EN](https://img.shields.io/badge/Language-EN-blue)](README.en.md)
47
+
48
+ Слоистый сборщик контекста для LLM-промптов. Три независимых, компонуемых
49
+ слоя кормят модель: **RAG по документам**, **сжатая история сессии** и
50
+ опциональный **профиль пользователя**. Подключаемое векторное хранилище,
51
+ подключаемый токенайзер, подключаемая стратегия сжатия.
52
+
53
+ [English version](README.en.md)
54
+
55
+ ## Зачем
56
+
57
+ Прод-LLM-приложения упираются в одну и ту же стену: модели нужен контекст,
58
+ но окно конечно. Собранная вручную сборка промпта превращается в кашу:
59
+ документы ищутся отдельно от истории, system prompt дублируется, и каждая
60
+ команда переписывает один и тот же клей.
61
+
62
+ `protoprompt` разделяет три задачи и даёт каждой чистый протокол:
63
+
64
+ - `StoreProtocol` — векторное хранилище (in-memory для тестов, ChromaDB для прода).
65
+ - `StrategyProtocol` — как сжимать старые ходы длинной сессии.
66
+ - `TokenCounter` — как считать бюджет финального промпта.
67
+
68
+ `ContextBuilder` оркестрирует все три. Результат — единый `system_prompt`
69
+ плюс структурированный `ContextOutput` с описанием того, что вошло (head,
70
+ tail, RAG, profile), чтобы UI мог показать provenance.
71
+
72
+ ## Установка
73
+
74
+ ```bash
75
+ pip install protoprompt
76
+
77
+ # С ChromaDB-бэкендом
78
+ pip install "protoprompt[chroma]"
79
+
80
+ # С tiktoken-токенайзером
81
+ pip install "protoprompt[tiktoken]"
82
+
83
+ # Для разработки и документации
84
+ pip install "protoprompt[chroma,dev]"
85
+ ```
86
+
87
+ ## Быстрый старт
88
+
89
+ ```python
90
+ import asyncio
91
+ from protoprompt import (
92
+ InMemStore,
93
+ ContextBuilder,
94
+ ContextInput,
95
+ Pipeline,
96
+ HeuristicStrategy,
97
+ Session,
98
+ )
99
+
100
+
101
+ class MyLLM:
102
+ async def chat(self, messages, model="", **options):
103
+ return "заглушка"
104
+
105
+ async def embed(self, texts, model=""):
106
+ # замените на реальные эмбеддинги
107
+ return [[0.1] * 384 for _ in texts]
108
+
109
+
110
+ async def main():
111
+ store = InMemStore()
112
+ store.add("doc-1", ["Париж — столица Франции."], [[0.5] * 384])
113
+ llm = MyLLM()
114
+
115
+ builder = ContextBuilder(store, llm)
116
+ out = await builder.build(ContextInput(
117
+ query="Какая столица Франции?",
118
+ system_prompt="Ты учитель географии.",
119
+ doc_ids=[1],
120
+ ))
121
+ print(out.system_prompt)
122
+
123
+ pipeline = Pipeline(
124
+ store, llm,
125
+ strategy=HeuristicStrategy(),
126
+ compress_every_n=10,
127
+ )
128
+ session = Session(chat_id="c1", messages=[
129
+ {"role": "user", "content": "Привет"},
130
+ {"role": "assistant", "content": "Здравствуйте!"},
131
+ ])
132
+ if pipeline.should_compress(len(session.messages)):
133
+ await pipeline.compress_and_store(session)
134
+
135
+
136
+ asyncio.run(main())
137
+ ```
138
+
139
+ ## Архитектура
140
+
141
+ ```
142
+ +--------------------+
143
+ | ContextBuilder |
144
+ | (оркестратор) |
145
+ +---------+----------+
146
+ |
147
+ +------------------+------------------+------------------+
148
+ | | | |
149
+ v v v v
150
+ +---------------+ +----------------+ +---------------+ +---------+
151
+ | RAG-поиск | | Память сессии | | Профиль польз.| | Store |
152
+ | (vector top-k)| | (сжатая) | | (из LLM) | | query |
153
+ +---------------+ +----------------+ +---------------+ +---------+
154
+ | | |
155
+ +--------+---------+--------+---------+
156
+ | |
157
+ v v
158
+ +----------------+ +----------------+
159
+ | TokenCounter | | StoreProtocol |
160
+ | (pluggable) | | (in-mem/chroma)|
161
+ +----------------+ +----------------+
162
+ ```
163
+
164
+ ## Публичный API
165
+
166
+ | Модуль | Экспорты |
167
+ |--------------------------|---------------------------------------------------------------------|
168
+ | `protoprompt` | `Pipeline`, `ContextBuilder`, `ContextInput`, `ContextOutput` |
169
+ | `protoprompt.store` | `StoreProtocol`, `InMemStore`, `ChromaStore` |
170
+ | `protoprompt.session` | `Session`, `CompressedBlock`, `HeuristicStrategy`, `LLMSummaryStrategy` |
171
+ | `protoprompt.profile` | `UserProfile`, `ProfileBuilder` |
172
+ | `protoprompt.tokens` | `TokenCounter`, `RegexTokenCounter`, `TiktokenCounter` |
173
+ | `protoprompt.llm` | `LLMClientProtocol` |
174
+
175
+ ## Документация
176
+
177
+ Полная документация собирается в двух языковых версиях:
178
+
179
+ - 🇷🇺 Русская: <https://idxeed.github.io/protoprompt/ru/>
180
+ - 🇬🇧 English: <https://idxeed.github.io/protoprompt/en/>
181
+
182
+ Локальная сборка:
183
+
184
+ ```bash
185
+ pip install "protoprompt[dev]"
186
+ python scripts/build_docs.py --serve # обе версии на разных портах
187
+ ```
188
+
189
+ ## Разработка
190
+
191
+ ```bash
192
+ git clone https://github.com/Idxeed/protoprompt
193
+ cd protoprompt
194
+ python -m venv .venv && source .venv/bin/activate
195
+ pip install -e ".[chroma,dev]"
196
+ pytest
197
+ ```
198
+
199
+ ## Лицензия
200
+
201
+ MIT — см. [LICENSE](LICENSE).
@@ -0,0 +1,164 @@
1
+ # protoprompt
2
+
3
+ [![CI](https://github.com/Idxeed/protoprompt/actions/workflows/ci.yml/badge.svg)](https://github.com/Idxeed/protoprompt/actions/workflows/ci.yml)
4
+ [![Coverage](https://img.shields.io/codecov/c/github/Idxeed/protoprompt)](https://codecov.io/gh/Idxeed/protoprompt)
5
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue)](https://www.python.org/)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
7
+ [![RU](https://img.shields.io/badge/%D0%AF%D0%B7%D1%8B%D0%BA-RU-blue)](README.ru.md)
8
+ [![EN](https://img.shields.io/badge/Language-EN-blue)](README.en.md)
9
+
10
+ [Русская версия](README.ru.md)
11
+
12
+ Layered context builder for LLM prompts. Three independent, composable
13
+ layers feed the model: **RAG over documents**, **compressed session
14
+ memory**, and an optional **user profile**. Pluggable vector store,
15
+ pluggable tokenizer, pluggable compression strategy.
16
+
17
+ ## Why
18
+
19
+ Production LLM apps hit the same wall: the model needs context, but the
20
+ context window is finite. Hand-rolled prompt assembly gets messy:
21
+ documents are queried separately from session history, the system prompt
22
+ gets duplicated, and you end up rewriting the same glue code per project.
23
+
24
+ `protoprompt` separates the three concerns and gives each a clean
25
+ protocol:
26
+
27
+ - `StoreProtocol` — vector storage (in-memory for tests, ChromaDB for prod).
28
+ - `StrategyProtocol` — how to compress old turns of a long session.
29
+ - `TokenCounter` — how to budget the final prompt.
30
+
31
+ The `ContextBuilder` orchestrates all three. The result is a single
32
+ `system_prompt` plus a structured `ContextOutput` describing what went in
33
+ (head, tail, RAG, profile) so the UI can show provenance.
34
+
35
+ ## Install
36
+
37
+ ```bash
38
+ pip install protoprompt
39
+
40
+ # With ChromaDB backend
41
+ pip install "protoprompt[chroma]"
42
+
43
+ # With tiktoken-based tokenizer
44
+ pip install "protoprompt[tiktoken]"
45
+
46
+ # Dev / docs
47
+ pip install "protoprompt[chroma,dev]"
48
+ ```
49
+
50
+ ## Quickstart
51
+
52
+ ```python
53
+ import asyncio
54
+ from protoprompt import (
55
+ InMemStore,
56
+ ContextBuilder,
57
+ ContextInput,
58
+ Pipeline,
59
+ HeuristicStrategy,
60
+ Session,
61
+ )
62
+
63
+
64
+ class MyLLM:
65
+ async def chat(self, messages, model="", **options):
66
+ return "stub"
67
+
68
+ async def embed(self, texts, model=""):
69
+ # replace with real embeddings
70
+ return [[0.1] * 384 for _ in texts]
71
+
72
+
73
+ async def main():
74
+ store = InMemStore()
75
+ store.add("doc-1", ["Paris is the capital of France."], [[0.5] * 384])
76
+ llm = MyLLM()
77
+
78
+ builder = ContextBuilder(store, llm)
79
+ out = await builder.build(ContextInput(
80
+ query="What is the capital of France?",
81
+ system_prompt="You are a geography tutor.",
82
+ doc_ids=[1],
83
+ ))
84
+ print(out.system_prompt)
85
+
86
+ pipeline = Pipeline(
87
+ store, llm,
88
+ strategy=HeuristicStrategy(),
89
+ compress_every_n=10,
90
+ )
91
+ session = Session(chat_id="c1", messages=[
92
+ {"role": "user", "content": "Hi"},
93
+ {"role": "assistant", "content": "Hello!"},
94
+ ])
95
+ if pipeline.should_compress(len(session.messages)):
96
+ await pipeline.compress_and_store(session)
97
+
98
+
99
+ asyncio.run(main())
100
+ ```
101
+
102
+ ## Architecture
103
+
104
+ ```
105
+ +--------------------+
106
+ | ContextBuilder |
107
+ | (orchestrator) |
108
+ +---------+----------+
109
+ |
110
+ +------------------+------------------+------------------+
111
+ | | | |
112
+ v v v v
113
+ +---------------+ +----------------+ +---------------+ +---------+
114
+ | RAG retrieval | | Session memory | | User profile | | Store |
115
+ | (vector top-k)| | (compressed) | | (LLM-derived) | | query |
116
+ +---------------+ +----------------+ +---------------+ +---------+
117
+ | | |
118
+ +--------+---------+--------+---------+
119
+ | |
120
+ v v
121
+ +----------------+ +----------------+
122
+ | TokenCounter | | StoreProtocol |
123
+ | (pluggable) | | (in-mem/chroma)|
124
+ +----------------+ +----------------+
125
+ ```
126
+
127
+ ## Public API
128
+
129
+ | Module | Exports |
130
+ |--------------------------|-------------------------------------------------------------------|
131
+ | `protoprompt` | `Pipeline`, `ContextBuilder`, `ContextInput`, `ContextOutput` |
132
+ | `protoprompt.store` | `StoreProtocol`, `InMemStore`, `ChromaStore` |
133
+ | `protoprompt.session` | `Session`, `CompressedBlock`, `HeuristicStrategy`, `LLMSummaryStrategy` |
134
+ | `protoprompt.profile` | `UserProfile`, `ProfileBuilder` |
135
+ | `protoprompt.tokens` | `TokenCounter`, `RegexTokenCounter`, `TiktokenCounter` |
136
+ | `protoprompt.llm` | `LLMClientProtocol` |
137
+
138
+ ## Documentation
139
+
140
+ Full docs are built in two languages:
141
+
142
+ - 🇷🇺 Russian: <https://idxeed.github.io/protoprompt/ru/>
143
+ - 🇬🇧 English: <https://idxeed.github.io/protoprompt/en/>
144
+
145
+ Build locally:
146
+
147
+ ```bash
148
+ pip install "protoprompt[dev]"
149
+ python scripts/build_docs.py --serve # both versions on different ports
150
+ ```
151
+
152
+ ## Development
153
+
154
+ ```bash
155
+ git clone https://github.com/Idxeed/protoprompt
156
+ cd protoprompt
157
+ python -m venv .venv && source .venv/bin/activate
158
+ pip install -e ".[chroma,dev]"
159
+ pytest
160
+ ```
161
+
162
+ ## License
163
+
164
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,163 @@
1
+ # protoprompt
2
+
3
+ [![CI](https://github.com/Idxeed/protoprompt/actions/workflows/ci.yml/badge.svg)](https://github.com/Idxeed/protoprompt/actions/workflows/ci.yml)
4
+ [![Coverage](https://img.shields.io/codecov/c/github/Idxeed/protoprompt)](https://codecov.io/gh/Idxeed/protoprompt)
5
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue)](https://www.python.org/)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
7
+ [![RU](https://img.shields.io/badge/%D0%AF%D0%B7%D1%8B%D0%BA-RU-blue)](README.ru.md)
8
+ [![EN](https://img.shields.io/badge/Language-EN-blue)](README.en.md)
9
+
10
+ Слоистый сборщик контекста для LLM-промптов. Три независимых, компонуемых
11
+ слоя кормят модель: **RAG по документам**, **сжатая история сессии** и
12
+ опциональный **профиль пользователя**. Подключаемое векторное хранилище,
13
+ подключаемый токенайзер, подключаемая стратегия сжатия.
14
+
15
+ [English version](README.en.md)
16
+
17
+ ## Зачем
18
+
19
+ Прод-LLM-приложения упираются в одну и ту же стену: модели нужен контекст,
20
+ но окно конечно. Собранная вручную сборка промпта превращается в кашу:
21
+ документы ищутся отдельно от истории, system prompt дублируется, и каждая
22
+ команда переписывает один и тот же клей.
23
+
24
+ `protoprompt` разделяет три задачи и даёт каждой чистый протокол:
25
+
26
+ - `StoreProtocol` — векторное хранилище (in-memory для тестов, ChromaDB для прода).
27
+ - `StrategyProtocol` — как сжимать старые ходы длинной сессии.
28
+ - `TokenCounter` — как считать бюджет финального промпта.
29
+
30
+ `ContextBuilder` оркестрирует все три. Результат — единый `system_prompt`
31
+ плюс структурированный `ContextOutput` с описанием того, что вошло (head,
32
+ tail, RAG, profile), чтобы UI мог показать provenance.
33
+
34
+ ## Установка
35
+
36
+ ```bash
37
+ pip install protoprompt
38
+
39
+ # С ChromaDB-бэкендом
40
+ pip install "protoprompt[chroma]"
41
+
42
+ # С tiktoken-токенайзером
43
+ pip install "protoprompt[tiktoken]"
44
+
45
+ # Для разработки и документации
46
+ pip install "protoprompt[chroma,dev]"
47
+ ```
48
+
49
+ ## Быстрый старт
50
+
51
+ ```python
52
+ import asyncio
53
+ from protoprompt import (
54
+ InMemStore,
55
+ ContextBuilder,
56
+ ContextInput,
57
+ Pipeline,
58
+ HeuristicStrategy,
59
+ Session,
60
+ )
61
+
62
+
63
+ class MyLLM:
64
+ async def chat(self, messages, model="", **options):
65
+ return "заглушка"
66
+
67
+ async def embed(self, texts, model=""):
68
+ # замените на реальные эмбеддинги
69
+ return [[0.1] * 384 for _ in texts]
70
+
71
+
72
+ async def main():
73
+ store = InMemStore()
74
+ store.add("doc-1", ["Париж — столица Франции."], [[0.5] * 384])
75
+ llm = MyLLM()
76
+
77
+ builder = ContextBuilder(store, llm)
78
+ out = await builder.build(ContextInput(
79
+ query="Какая столица Франции?",
80
+ system_prompt="Ты учитель географии.",
81
+ doc_ids=[1],
82
+ ))
83
+ print(out.system_prompt)
84
+
85
+ pipeline = Pipeline(
86
+ store, llm,
87
+ strategy=HeuristicStrategy(),
88
+ compress_every_n=10,
89
+ )
90
+ session = Session(chat_id="c1", messages=[
91
+ {"role": "user", "content": "Привет"},
92
+ {"role": "assistant", "content": "Здравствуйте!"},
93
+ ])
94
+ if pipeline.should_compress(len(session.messages)):
95
+ await pipeline.compress_and_store(session)
96
+
97
+
98
+ asyncio.run(main())
99
+ ```
100
+
101
+ ## Архитектура
102
+
103
+ ```
104
+ +--------------------+
105
+ | ContextBuilder |
106
+ | (оркестратор) |
107
+ +---------+----------+
108
+ |
109
+ +------------------+------------------+------------------+
110
+ | | | |
111
+ v v v v
112
+ +---------------+ +----------------+ +---------------+ +---------+
113
+ | RAG-поиск | | Память сессии | | Профиль польз.| | Store |
114
+ | (vector top-k)| | (сжатая) | | (из LLM) | | query |
115
+ +---------------+ +----------------+ +---------------+ +---------+
116
+ | | |
117
+ +--------+---------+--------+---------+
118
+ | |
119
+ v v
120
+ +----------------+ +----------------+
121
+ | TokenCounter | | StoreProtocol |
122
+ | (pluggable) | | (in-mem/chroma)|
123
+ +----------------+ +----------------+
124
+ ```
125
+
126
+ ## Публичный API
127
+
128
+ | Модуль | Экспорты |
129
+ |--------------------------|---------------------------------------------------------------------|
130
+ | `protoprompt` | `Pipeline`, `ContextBuilder`, `ContextInput`, `ContextOutput` |
131
+ | `protoprompt.store` | `StoreProtocol`, `InMemStore`, `ChromaStore` |
132
+ | `protoprompt.session` | `Session`, `CompressedBlock`, `HeuristicStrategy`, `LLMSummaryStrategy` |
133
+ | `protoprompt.profile` | `UserProfile`, `ProfileBuilder` |
134
+ | `protoprompt.tokens` | `TokenCounter`, `RegexTokenCounter`, `TiktokenCounter` |
135
+ | `protoprompt.llm` | `LLMClientProtocol` |
136
+
137
+ ## Документация
138
+
139
+ Полная документация собирается в двух языковых версиях:
140
+
141
+ - 🇷🇺 Русская: <https://idxeed.github.io/protoprompt/ru/>
142
+ - 🇬🇧 English: <https://idxeed.github.io/protoprompt/en/>
143
+
144
+ Локальная сборка:
145
+
146
+ ```bash
147
+ pip install "protoprompt[dev]"
148
+ python scripts/build_docs.py --serve # обе версии на разных портах
149
+ ```
150
+
151
+ ## Разработка
152
+
153
+ ```bash
154
+ git clone https://github.com/Idxeed/protoprompt
155
+ cd protoprompt
156
+ python -m venv .venv && source .venv/bin/activate
157
+ pip install -e ".[chroma,dev]"
158
+ pytest
159
+ ```
160
+
161
+ ## Лицензия
162
+
163
+ MIT — см. [LICENSE](LICENSE).
@@ -0,0 +1,3 @@
1
+ # API: context
2
+
3
+ ::: protoprompt.context
@@ -0,0 +1,17 @@
1
+ # API: injector
2
+
3
+ ## ContextBuilder
4
+
5
+ ::: protoprompt.injector.ContextBuilder
6
+
7
+ ## TokenBudgetedContextBuilder
8
+
9
+ ::: protoprompt.injector_budgeted.TokenBudgetedContextBuilder
10
+
11
+ ## BudgetReport
12
+
13
+ ::: protoprompt.injector_budgeted.BudgetReport
14
+
15
+ ## Exceptions
16
+
17
+ ::: protoprompt.exceptions
@@ -0,0 +1,5 @@
1
+ # API: pipeline
2
+
3
+ ## Pipeline
4
+
5
+ ::: protoprompt.pipeline.Pipeline
@@ -0,0 +1,9 @@
1
+ # API: profile
2
+
3
+ ## UserProfile
4
+
5
+ ::: protoprompt.profile.types
6
+
7
+ ## ProfileBuilder
8
+
9
+ ::: protoprompt.profile.builder.ProfileBuilder
@@ -0,0 +1,17 @@
1
+ # API: session
2
+
3
+ ## Session & CompressedBlock
4
+
5
+ ::: protoprompt.session.types
6
+
7
+ ## HeuristicStrategy
8
+
9
+ ::: protoprompt.session.strategy.HeuristicStrategy
10
+
11
+ ## LLMSummaryStrategy
12
+
13
+ ::: protoprompt.session.strategy.LLMSummaryStrategy
14
+
15
+ ## Compressor
16
+
17
+ ::: protoprompt.session.compressor.Compressor
@@ -0,0 +1,13 @@
1
+ # API: store
2
+
3
+ ## StoreProtocol
4
+
5
+ ::: protoprompt.store.protocol
6
+
7
+ ## InMemStore
8
+
9
+ ::: protoprompt.store.memory.InMemStore
10
+
11
+ ## ChromaStore
12
+
13
+ ::: protoprompt.store.chroma.ChromaStore
@@ -0,0 +1,13 @@
1
+ # API: tokens
2
+
3
+ ## TokenCounter
4
+
5
+ ::: protoprompt.tokens.protocol
6
+
7
+ ## RegexTokenCounter
8
+
9
+ ::: protoprompt.tokens.regex_counter
10
+
11
+ ## TiktokenCounter
12
+
13
+ ::: protoprompt.tokens.tiktoken_adapter