streetai-memory 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 (29) hide show
  1. streetai_memory-0.1.0/LICENSE +19 -0
  2. streetai_memory-0.1.0/PKG-INFO +289 -0
  3. streetai_memory-0.1.0/README.md +228 -0
  4. streetai_memory-0.1.0/pyproject.toml +68 -0
  5. streetai_memory-0.1.0/setup.cfg +4 -0
  6. streetai_memory-0.1.0/streetai/__init__.py +63 -0
  7. streetai_memory-0.1.0/streetai/adapters/__init__.py +16 -0
  8. streetai_memory-0.1.0/streetai/adapters/anthropic.py +147 -0
  9. streetai_memory-0.1.0/streetai/adapters/gemini.py +185 -0
  10. streetai_memory-0.1.0/streetai/adapters/openai.py +152 -0
  11. streetai_memory-0.1.0/streetai/chunking.py +115 -0
  12. streetai_memory-0.1.0/streetai/config.py +70 -0
  13. streetai_memory-0.1.0/streetai/decay.py +35 -0
  14. streetai_memory-0.1.0/streetai/encoder.py +45 -0
  15. streetai_memory-0.1.0/streetai/memory.py +369 -0
  16. streetai_memory-0.1.0/streetai/prompt.py +25 -0
  17. streetai_memory-0.1.0/streetai/py.typed +0 -0
  18. streetai_memory-0.1.0/streetai/signal.py +87 -0
  19. streetai_memory-0.1.0/streetai/stack.py +55 -0
  20. streetai_memory-0.1.0/streetai/store.py +130 -0
  21. streetai_memory-0.1.0/streetai_memory.egg-info/PKG-INFO +289 -0
  22. streetai_memory-0.1.0/streetai_memory.egg-info/SOURCES.txt +27 -0
  23. streetai_memory-0.1.0/streetai_memory.egg-info/dependency_links.txt +1 -0
  24. streetai_memory-0.1.0/streetai_memory.egg-info/requires.txt +24 -0
  25. streetai_memory-0.1.0/streetai_memory.egg-info/top_level.txt +1 -0
  26. streetai_memory-0.1.0/tests/test_adapters.py +246 -0
  27. streetai_memory-0.1.0/tests/test_chunking.py +81 -0
  28. streetai_memory-0.1.0/tests/test_decay.py +66 -0
  29. streetai_memory-0.1.0/tests/test_memory.py +162 -0
@@ -0,0 +1,19 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+
17
+ Copyright 2026 Street AI
18
+
19
+ Full license text: https://www.apache.org/licenses/LICENSE-2.0.txt
@@ -0,0 +1,289 @@
1
+ Metadata-Version: 2.4
2
+ Name: streetai-memory
3
+ Version: 0.1.0
4
+ Summary: Continuously learning memory layer for LLM applications: signals, stacks, decay, two-tier retrieval.
5
+ Author: Tem-Degu
6
+ License: Apache License
7
+ Version 2.0, January 2004
8
+ http://www.apache.org/licenses/
9
+
10
+ Licensed under the Apache License, Version 2.0 (the "License");
11
+ you may not use this file except in compliance with the License.
12
+ You may obtain a copy of the License at
13
+
14
+ http://www.apache.org/licenses/LICENSE-2.0
15
+
16
+ Unless required by applicable law or agreed to in writing, software
17
+ distributed under the License is distributed on an "AS IS" BASIS,
18
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19
+ See the License for the specific language governing permissions and
20
+ limitations under the License.
21
+
22
+ Copyright 2026 Street AI
23
+
24
+ Full license text: https://www.apache.org/licenses/LICENSE-2.0.txt
25
+
26
+ Project-URL: Homepage, https://github.com/Tem-Degu/streetai-memory
27
+ Project-URL: Repository, https://github.com/Tem-Degu/streetai-memory
28
+ Project-URL: Issues, https://github.com/Tem-Degu/streetai-memory/issues
29
+ Keywords: llm,memory,ai,rag,embeddings,chatbot
30
+ Classifier: Development Status :: 3 - Alpha
31
+ Classifier: Intended Audience :: Developers
32
+ Classifier: License :: OSI Approved :: Apache Software License
33
+ Classifier: Programming Language :: Python :: 3
34
+ Classifier: Programming Language :: Python :: 3.10
35
+ Classifier: Programming Language :: Python :: 3.11
36
+ Classifier: Programming Language :: Python :: 3.12
37
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
38
+ Requires-Python: >=3.10
39
+ Description-Content-Type: text/markdown
40
+ License-File: LICENSE
41
+ Requires-Dist: numpy<3,>=1.24
42
+ Requires-Dist: faiss-cpu>=1.7.4
43
+ Requires-Dist: fastembed>=0.3.0
44
+ Provides-Extra: anthropic
45
+ Requires-Dist: anthropic>=0.40.0; extra == "anthropic"
46
+ Provides-Extra: openai
47
+ Requires-Dist: openai>=1.50.0; extra == "openai"
48
+ Provides-Extra: gemini
49
+ Requires-Dist: google-genai>=0.3.0; extra == "gemini"
50
+ Provides-Extra: all
51
+ Requires-Dist: anthropic>=0.40.0; extra == "all"
52
+ Requires-Dist: openai>=1.50.0; extra == "all"
53
+ Requires-Dist: google-genai>=0.3.0; extra == "all"
54
+ Provides-Extra: dev
55
+ Requires-Dist: pytest>=8.0; extra == "dev"
56
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
57
+ Requires-Dist: ruff>=0.5; extra == "dev"
58
+ Requires-Dist: build>=1.2; extra == "dev"
59
+ Requires-Dist: twine>=5.0; extra == "dev"
60
+ Dynamic: license-file
61
+
62
+ # Street AI
63
+
64
+ > Continuously learning memory layer for LLM applications.
65
+ > Your AI's memory grows forever. Your token bill doesn't.
66
+
67
+ Street AI sits between your application and the LLM API. It stores conversation as
68
+ **signals** organized into **stacks**, decays old data automatically, and retrieves
69
+ only what's relevant on each turn — so you send a tiny prompt instead of the full
70
+ conversation history.
71
+
72
+ ## Status
73
+
74
+ Alpha (`0.1.0`). API will change. Pin a version if you depend on it.
75
+
76
+ ## Install
77
+
78
+ ```bash
79
+ pip install streetai-memory
80
+ ```
81
+
82
+ The PyPI name is `streetai-memory`; the import path is `streetai`:
83
+
84
+ ```python
85
+ from streetai import Memory, MemoryRegistry, Config
86
+ ```
87
+
88
+ First use downloads a ~25MB embedding model (`all-MiniLM-L6-v2`) into a local cache.
89
+
90
+ To install with provider adapters:
91
+
92
+ ```bash
93
+ pip install "streetai-memory[anthropic]" # Anthropic
94
+ pip install "streetai-memory[openai]" # OpenAI (also DeepSeek, Together, Groq)
95
+ pip install "streetai-memory[gemini]" # Google Gemini
96
+ pip install "streetai-memory[all]" # all of the above
97
+ ```
98
+
99
+ ## Quickstart
100
+
101
+ ```python
102
+ from streetai import MemoryRegistry
103
+
104
+ registry = MemoryRegistry("./memory.db")
105
+ mem = registry.get("user_123")
106
+
107
+ mem.add_message("Hi, I'm planning a trip to Japan.", role="user")
108
+ mem.add_message("Great! Which cities?", role="assistant")
109
+
110
+ prompt = mem.build_prompt("What did I say about Japan?")
111
+
112
+ # prompt.messages -> list of {role, content} ready for any LLM API
113
+ # prompt.retrieved -> signals that were pulled in (pass to post_process)
114
+ # prompt.inspector -> debug info (stacks activated, scores, etc.)
115
+
116
+ # After your LLM responds:
117
+ # response_text = your_llm(messages=prompt.messages)
118
+ # mem.post_process(prompt.retrieved, response_text)
119
+ # mem.add_message("What did I say about Japan?", role="user")
120
+ # mem.add_message(response_text, role="assistant")
121
+ ```
122
+
123
+ For a fully runnable version, see [`examples/quickstart.py`](./examples/quickstart.py).
124
+
125
+ ## Drop-in adapters
126
+
127
+ The adapters wrap a real provider client. You use the same SDK API you already know;
128
+ memory is read and written transparently on every call.
129
+
130
+ ### Anthropic
131
+
132
+ ```python
133
+ from anthropic import Anthropic
134
+ from streetai.adapters.anthropic import with_memory
135
+
136
+ client = with_memory(Anthropic(), memory_id="user_123")
137
+
138
+ response = client.messages.create(
139
+ model="claude-sonnet-4-6",
140
+ max_tokens=1024,
141
+ system="You are helpful.",
142
+ messages=[{"role": "user", "content": "What did I mention earlier?"}],
143
+ )
144
+ print(response.content[0].text)
145
+ ```
146
+
147
+ Full example: [`examples/anthropic_chat.py`](./examples/anthropic_chat.py).
148
+
149
+ ### OpenAI
150
+
151
+ ```python
152
+ from openai import OpenAI
153
+ from streetai.adapters.openai import with_memory
154
+
155
+ client = with_memory(OpenAI(), memory_id="user_123")
156
+
157
+ response = client.chat.completions.create(
158
+ model="gpt-4o-mini",
159
+ messages=[{"role": "user", "content": "What did I mention earlier?"}],
160
+ )
161
+ print(response.choices[0].message.content)
162
+ ```
163
+
164
+ Full example: [`examples/openai_chat.py`](./examples/openai_chat.py).
165
+
166
+ ### DeepSeek (uses the OpenAI adapter)
167
+
168
+ DeepSeek is OpenAI-API-compatible. Use the OpenAI adapter with `base_url`:
169
+
170
+ ```python
171
+ import os
172
+ from openai import OpenAI
173
+ from streetai.adapters.openai import with_memory
174
+
175
+ deepseek = OpenAI(
176
+ api_key=os.environ["DEEPSEEK_API_KEY"],
177
+ base_url="https://api.deepseek.com/v1",
178
+ )
179
+ client = with_memory(deepseek, memory_id="user_123")
180
+
181
+ response = client.chat.completions.create(
182
+ model="deepseek-chat",
183
+ messages=[{"role": "user", "content": "What did I mention earlier?"}],
184
+ )
185
+ ```
186
+
187
+ The same pattern works for **Together**, **Anyscale**, **Groq**, and any other
188
+ OpenAI-compatible endpoint. Full example: [`examples/deepseek_chat.py`](./examples/deepseek_chat.py).
189
+
190
+ ### Google Gemini
191
+
192
+ ```python
193
+ from google import genai
194
+ from streetai.adapters.gemini import with_memory
195
+
196
+ client = with_memory(genai.Client(api_key="..."), memory_id="user_123")
197
+
198
+ response = client.models.generate_content(
199
+ model="gemini-2.0-flash",
200
+ contents="What did I mention earlier?",
201
+ )
202
+ print(response.text)
203
+ ```
204
+
205
+ Full example: [`examples/gemini_chat.py`](./examples/gemini_chat.py).
206
+
207
+ ## How it works
208
+
209
+ ```
210
+ your message
211
+ |
212
+ v
213
+ [1] split into chunks (sentence-sized signals)
214
+ |
215
+ v
216
+ [2] embed each chunk to a 384-dim vector
217
+ |
218
+ v
219
+ [3] assign to a stack (cluster of related signals) by cosine similarity
220
+ |
221
+ v
222
+ [4] when a new query arrives:
223
+ - find top-K most relevant stacks (FAISS)
224
+ - within those stacks, surface signals that pass the activation threshold
225
+ - drop signals whose effective weight has decayed below death
226
+ |
227
+ v
228
+ [5] build a small prompt:
229
+ [retrieved context] + [last N messages verbatim] + [new query]
230
+ |
231
+ v
232
+ [6] after the LLM responds:
233
+ - boost signals that matched the response (they helped)
234
+ - demote signals that didn't (they were noise)
235
+ - decay continues until the signal is used again
236
+ ```
237
+
238
+ Signals refresh their age clock every time they're retrieved — frequently useful
239
+ data stays sharp; unused data fades. No retraining, no manual pruning.
240
+
241
+ ## Compared to alternatives
242
+
243
+ | | Plain chat history | RAG (vector DB) | Street AI |
244
+ |---|---|---|---|
245
+ | Prompt grows with conversation | Yes — linear | No (replaces history) | No (compresses history) |
246
+ | Recent context kept verbatim | Yes | No — replaced by retrieval | Yes — recency window |
247
+ | Time-aware (decay) | No | No | Yes — built in |
248
+ | Learns from outcomes | No | No | Yes — boost/demote |
249
+ | Self-organizing | N/A | Manual chunking | Yes — auto-stacks |
250
+ | Cross-provider | Yes | Sometimes | Yes |
251
+
252
+ ## Configuration
253
+
254
+ Override defaults with `Config`:
255
+
256
+ ```python
257
+ from streetai import MemoryRegistry, Config
258
+
259
+ cfg = Config(
260
+ recency_turns=5, # last 5 messages verbatim (default 3)
261
+ decay_rate=1.0/86400, # 1-day half-life (default ~ 1 week)
262
+ stack_threshold=0.65, # tighter stack assignment (default 0.55)
263
+ activation_threshold=0.1, # min score for a signal to surface (default 0.15)
264
+ )
265
+
266
+ registry = MemoryRegistry("./memory.db", config=cfg)
267
+ ```
268
+
269
+ All tunables: see [`streetai/config.py`](./streetai/config.py).
270
+
271
+ ## Limitations (v0.1)
272
+
273
+ - **Sync clients only.** Async wrappers come later.
274
+ - **Non-streaming only.** `stream=True` raises `NotImplementedError`.
275
+ - **English-tuned defaults.** Chunking and thresholds may need tuning for other languages.
276
+ - **fastembed is required.** Pluggable encoders come in a future version.
277
+
278
+ ## Development
279
+
280
+ ```bash
281
+ git clone https://github.com/Tem-Degu/streetai-memory.git
282
+ cd streetai-memory
283
+ pip install -e ".[dev]"
284
+ pytest
285
+ ```
286
+
287
+ ## License
288
+
289
+ Apache 2.0
@@ -0,0 +1,228 @@
1
+ # Street AI
2
+
3
+ > Continuously learning memory layer for LLM applications.
4
+ > Your AI's memory grows forever. Your token bill doesn't.
5
+
6
+ Street AI sits between your application and the LLM API. It stores conversation as
7
+ **signals** organized into **stacks**, decays old data automatically, and retrieves
8
+ only what's relevant on each turn — so you send a tiny prompt instead of the full
9
+ conversation history.
10
+
11
+ ## Status
12
+
13
+ Alpha (`0.1.0`). API will change. Pin a version if you depend on it.
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ pip install streetai-memory
19
+ ```
20
+
21
+ The PyPI name is `streetai-memory`; the import path is `streetai`:
22
+
23
+ ```python
24
+ from streetai import Memory, MemoryRegistry, Config
25
+ ```
26
+
27
+ First use downloads a ~25MB embedding model (`all-MiniLM-L6-v2`) into a local cache.
28
+
29
+ To install with provider adapters:
30
+
31
+ ```bash
32
+ pip install "streetai-memory[anthropic]" # Anthropic
33
+ pip install "streetai-memory[openai]" # OpenAI (also DeepSeek, Together, Groq)
34
+ pip install "streetai-memory[gemini]" # Google Gemini
35
+ pip install "streetai-memory[all]" # all of the above
36
+ ```
37
+
38
+ ## Quickstart
39
+
40
+ ```python
41
+ from streetai import MemoryRegistry
42
+
43
+ registry = MemoryRegistry("./memory.db")
44
+ mem = registry.get("user_123")
45
+
46
+ mem.add_message("Hi, I'm planning a trip to Japan.", role="user")
47
+ mem.add_message("Great! Which cities?", role="assistant")
48
+
49
+ prompt = mem.build_prompt("What did I say about Japan?")
50
+
51
+ # prompt.messages -> list of {role, content} ready for any LLM API
52
+ # prompt.retrieved -> signals that were pulled in (pass to post_process)
53
+ # prompt.inspector -> debug info (stacks activated, scores, etc.)
54
+
55
+ # After your LLM responds:
56
+ # response_text = your_llm(messages=prompt.messages)
57
+ # mem.post_process(prompt.retrieved, response_text)
58
+ # mem.add_message("What did I say about Japan?", role="user")
59
+ # mem.add_message(response_text, role="assistant")
60
+ ```
61
+
62
+ For a fully runnable version, see [`examples/quickstart.py`](./examples/quickstart.py).
63
+
64
+ ## Drop-in adapters
65
+
66
+ The adapters wrap a real provider client. You use the same SDK API you already know;
67
+ memory is read and written transparently on every call.
68
+
69
+ ### Anthropic
70
+
71
+ ```python
72
+ from anthropic import Anthropic
73
+ from streetai.adapters.anthropic import with_memory
74
+
75
+ client = with_memory(Anthropic(), memory_id="user_123")
76
+
77
+ response = client.messages.create(
78
+ model="claude-sonnet-4-6",
79
+ max_tokens=1024,
80
+ system="You are helpful.",
81
+ messages=[{"role": "user", "content": "What did I mention earlier?"}],
82
+ )
83
+ print(response.content[0].text)
84
+ ```
85
+
86
+ Full example: [`examples/anthropic_chat.py`](./examples/anthropic_chat.py).
87
+
88
+ ### OpenAI
89
+
90
+ ```python
91
+ from openai import OpenAI
92
+ from streetai.adapters.openai import with_memory
93
+
94
+ client = with_memory(OpenAI(), memory_id="user_123")
95
+
96
+ response = client.chat.completions.create(
97
+ model="gpt-4o-mini",
98
+ messages=[{"role": "user", "content": "What did I mention earlier?"}],
99
+ )
100
+ print(response.choices[0].message.content)
101
+ ```
102
+
103
+ Full example: [`examples/openai_chat.py`](./examples/openai_chat.py).
104
+
105
+ ### DeepSeek (uses the OpenAI adapter)
106
+
107
+ DeepSeek is OpenAI-API-compatible. Use the OpenAI adapter with `base_url`:
108
+
109
+ ```python
110
+ import os
111
+ from openai import OpenAI
112
+ from streetai.adapters.openai import with_memory
113
+
114
+ deepseek = OpenAI(
115
+ api_key=os.environ["DEEPSEEK_API_KEY"],
116
+ base_url="https://api.deepseek.com/v1",
117
+ )
118
+ client = with_memory(deepseek, memory_id="user_123")
119
+
120
+ response = client.chat.completions.create(
121
+ model="deepseek-chat",
122
+ messages=[{"role": "user", "content": "What did I mention earlier?"}],
123
+ )
124
+ ```
125
+
126
+ The same pattern works for **Together**, **Anyscale**, **Groq**, and any other
127
+ OpenAI-compatible endpoint. Full example: [`examples/deepseek_chat.py`](./examples/deepseek_chat.py).
128
+
129
+ ### Google Gemini
130
+
131
+ ```python
132
+ from google import genai
133
+ from streetai.adapters.gemini import with_memory
134
+
135
+ client = with_memory(genai.Client(api_key="..."), memory_id="user_123")
136
+
137
+ response = client.models.generate_content(
138
+ model="gemini-2.0-flash",
139
+ contents="What did I mention earlier?",
140
+ )
141
+ print(response.text)
142
+ ```
143
+
144
+ Full example: [`examples/gemini_chat.py`](./examples/gemini_chat.py).
145
+
146
+ ## How it works
147
+
148
+ ```
149
+ your message
150
+ |
151
+ v
152
+ [1] split into chunks (sentence-sized signals)
153
+ |
154
+ v
155
+ [2] embed each chunk to a 384-dim vector
156
+ |
157
+ v
158
+ [3] assign to a stack (cluster of related signals) by cosine similarity
159
+ |
160
+ v
161
+ [4] when a new query arrives:
162
+ - find top-K most relevant stacks (FAISS)
163
+ - within those stacks, surface signals that pass the activation threshold
164
+ - drop signals whose effective weight has decayed below death
165
+ |
166
+ v
167
+ [5] build a small prompt:
168
+ [retrieved context] + [last N messages verbatim] + [new query]
169
+ |
170
+ v
171
+ [6] after the LLM responds:
172
+ - boost signals that matched the response (they helped)
173
+ - demote signals that didn't (they were noise)
174
+ - decay continues until the signal is used again
175
+ ```
176
+
177
+ Signals refresh their age clock every time they're retrieved — frequently useful
178
+ data stays sharp; unused data fades. No retraining, no manual pruning.
179
+
180
+ ## Compared to alternatives
181
+
182
+ | | Plain chat history | RAG (vector DB) | Street AI |
183
+ |---|---|---|---|
184
+ | Prompt grows with conversation | Yes — linear | No (replaces history) | No (compresses history) |
185
+ | Recent context kept verbatim | Yes | No — replaced by retrieval | Yes — recency window |
186
+ | Time-aware (decay) | No | No | Yes — built in |
187
+ | Learns from outcomes | No | No | Yes — boost/demote |
188
+ | Self-organizing | N/A | Manual chunking | Yes — auto-stacks |
189
+ | Cross-provider | Yes | Sometimes | Yes |
190
+
191
+ ## Configuration
192
+
193
+ Override defaults with `Config`:
194
+
195
+ ```python
196
+ from streetai import MemoryRegistry, Config
197
+
198
+ cfg = Config(
199
+ recency_turns=5, # last 5 messages verbatim (default 3)
200
+ decay_rate=1.0/86400, # 1-day half-life (default ~ 1 week)
201
+ stack_threshold=0.65, # tighter stack assignment (default 0.55)
202
+ activation_threshold=0.1, # min score for a signal to surface (default 0.15)
203
+ )
204
+
205
+ registry = MemoryRegistry("./memory.db", config=cfg)
206
+ ```
207
+
208
+ All tunables: see [`streetai/config.py`](./streetai/config.py).
209
+
210
+ ## Limitations (v0.1)
211
+
212
+ - **Sync clients only.** Async wrappers come later.
213
+ - **Non-streaming only.** `stream=True` raises `NotImplementedError`.
214
+ - **English-tuned defaults.** Chunking and thresholds may need tuning for other languages.
215
+ - **fastembed is required.** Pluggable encoders come in a future version.
216
+
217
+ ## Development
218
+
219
+ ```bash
220
+ git clone https://github.com/Tem-Degu/streetai-memory.git
221
+ cd streetai-memory
222
+ pip install -e ".[dev]"
223
+ pytest
224
+ ```
225
+
226
+ ## License
227
+
228
+ Apache 2.0
@@ -0,0 +1,68 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "streetai-memory"
7
+ version = "0.1.0"
8
+ description = "Continuously learning memory layer for LLM applications: signals, stacks, decay, two-tier retrieval."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = { file = "LICENSE" }
12
+ authors = [
13
+ { name = "Tem-Degu" }
14
+ ]
15
+ keywords = ["llm", "memory", "ai", "rag", "embeddings", "chatbot"]
16
+ classifiers = [
17
+ "Development Status :: 3 - Alpha",
18
+ "Intended Audience :: Developers",
19
+ "License :: OSI Approved :: Apache Software License",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
25
+ ]
26
+
27
+ dependencies = [
28
+ "numpy>=1.24,<3",
29
+ "faiss-cpu>=1.7.4",
30
+ "fastembed>=0.3.0",
31
+ ]
32
+
33
+ [project.optional-dependencies]
34
+ anthropic = ["anthropic>=0.40.0"]
35
+ openai = ["openai>=1.50.0"]
36
+ gemini = ["google-genai>=0.3.0"]
37
+ # DeepSeek uses the OpenAI-compatible API; install the `openai` extra.
38
+ all = [
39
+ "anthropic>=0.40.0",
40
+ "openai>=1.50.0",
41
+ "google-genai>=0.3.0",
42
+ ]
43
+ dev = [
44
+ "pytest>=8.0",
45
+ "pytest-asyncio>=0.23",
46
+ "ruff>=0.5",
47
+ "build>=1.2",
48
+ "twine>=5.0",
49
+ ]
50
+
51
+ [project.urls]
52
+ Homepage = "https://github.com/Tem-Degu/streetai-memory"
53
+ Repository = "https://github.com/Tem-Degu/streetai-memory"
54
+ Issues = "https://github.com/Tem-Degu/streetai-memory/issues"
55
+
56
+ [tool.setuptools.packages.find]
57
+ where = ["."]
58
+ include = ["streetai*"]
59
+
60
+ [tool.setuptools.package-data]
61
+ streetai = ["py.typed"]
62
+
63
+ [tool.ruff]
64
+ line-length = 100
65
+ target-version = "py310"
66
+
67
+ [tool.pytest.ini_options]
68
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,63 @@
1
+ """Street AI: continuously learning memory layer for LLM applications.
2
+
3
+ Quickstart:
4
+
5
+ from streetai import Memory, MemoryRegistry, Config
6
+
7
+ registry = MemoryRegistry("./memory.db")
8
+ mem = registry.get("user_123")
9
+
10
+ mem.add_message("Hello", role="user")
11
+ prompt = mem.build_prompt("What did I say?")
12
+ # prompt.messages -> list[{role, content}] ready for any LLM API
13
+ """
14
+ from __future__ import annotations
15
+
16
+ from .chunking import chunk_text
17
+ from .config import (
18
+ ACTIVATION_THRESHOLD,
19
+ BOOST_FACTOR,
20
+ Config,
21
+ DEATH_THRESHOLD,
22
+ DECAY_RATE,
23
+ DEFAULT_CONFIG,
24
+ DEMOTE_FACTOR,
25
+ EMBEDDING_DIM,
26
+ EMBEDDING_MODEL,
27
+ HIGH_RELEVANCE,
28
+ LOW_RELEVANCE,
29
+ MAX_BASE_WEIGHT,
30
+ MAX_THINKING_SPACE,
31
+ RECENCY_TURNS,
32
+ STACK_THRESHOLD,
33
+ TOP_STACKS,
34
+ )
35
+ from .decay import exponential_decay, half_life_to_decay_rate, time_to_death
36
+ from .encoder import encode # encoder() is available via streetai.encoder.encoder
37
+ from .memory import Memory, MemoryRegistry
38
+ from .prompt import Prompt
39
+ from .signal import Signal
40
+ from .stack import Stack
41
+ from .store import Store
42
+
43
+ __version__ = "0.1.0"
44
+
45
+ __all__ = [
46
+ # Primary API
47
+ "Memory",
48
+ "MemoryRegistry",
49
+ "Prompt",
50
+ "Config",
51
+ # Lower-level types (for power users)
52
+ "Signal",
53
+ "Stack",
54
+ "Store",
55
+ "chunk_text",
56
+ "encode",
57
+ "DEFAULT_CONFIG",
58
+ # Decay math (utility)
59
+ "exponential_decay",
60
+ "half_life_to_decay_rate",
61
+ "time_to_death",
62
+ "__version__",
63
+ ]
@@ -0,0 +1,16 @@
1
+ """Drop-in memory wrappers for popular LLM provider SDKs.
2
+
3
+ Each adapter exposes ``with_memory(client, memory_id)`` returning a thin proxy
4
+ that mimics the real client's API. The proxy intercepts chat-completion calls,
5
+ injects retrieved memory into the prompt, calls the underlying client, and
6
+ writes the new turn back to memory.
7
+
8
+ Adapters are intentionally lightweight (~100 lines each). For custom providers
9
+ or advanced needs, use ``Memory.build_prompt()`` and ``Memory.post_process()``
10
+ directly.
11
+
12
+ Available adapters:
13
+ - ``streetai.adapters.anthropic`` — wraps ``anthropic.Anthropic``
14
+ - ``streetai.adapters.openai`` — wraps ``openai.OpenAI`` (also DeepSeek, Together, etc.)
15
+ - ``streetai.adapters.gemini`` — wraps ``google.genai.Client`` (added in Day 4)
16
+ """