clsplusplus 4.0.2__tar.gz → 7.2.3__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.
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/PKG-INFO +91 -17
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/README.md +87 -16
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/pyproject.toml +19 -2
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/__init__.py +1 -1
- clsplusplus-7.2.3/src/clsplusplus/abuse_guard.py +486 -0
- clsplusplus-7.2.3/src/clsplusplus/api.py +3830 -0
- clsplusplus-7.2.3/src/clsplusplus/api_usage_analytics.py +237 -0
- clsplusplus-7.2.3/src/clsplusplus/config.py +355 -0
- clsplusplus-7.2.3/src/clsplusplus/cost_forecast.py +381 -0
- clsplusplus-7.2.3/src/clsplusplus/debug_console.py +194 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/demo_llm_calls.py +45 -9
- clsplusplus-7.2.3/src/clsplusplus/email_service.py +262 -0
- clsplusplus-7.2.3/src/clsplusplus/funnel_routes.py +95 -0
- clsplusplus-7.2.3/src/clsplusplus/geo.py +179 -0
- clsplusplus-7.2.3/src/clsplusplus/health_metrics.py +303 -0
- clsplusplus-7.2.3/src/clsplusplus/homepage_autopromote.py +293 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/integration_service.py +2 -2
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/local_routes.py +274 -37
- clsplusplus-7.2.3/src/clsplusplus/main.py +39 -0
- clsplusplus-7.2.3/src/clsplusplus/mcp_server.py +273 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/memory_phase.py +17 -1
- clsplusplus-7.2.3/src/clsplusplus/metering_v2/__init__.py +51 -0
- clsplusplus-7.2.3/src/clsplusplus/metering_v2/__main__.py +32 -0
- clsplusplus-7.2.3/src/clsplusplus/metering_v2/billing.py +189 -0
- clsplusplus-7.2.3/src/clsplusplus/metering_v2/healthcheck.py +381 -0
- clsplusplus-7.2.3/src/clsplusplus/metering_v2/notifier.py +171 -0
- clsplusplus-7.2.3/src/clsplusplus/metering_v2/pricing.py +103 -0
- clsplusplus-7.2.3/src/clsplusplus/metering_v2/reconciler.py +291 -0
- clsplusplus-7.2.3/src/clsplusplus/metering_v2/schema.py +58 -0
- clsplusplus-7.2.3/src/clsplusplus/metering_v2/writer.py +176 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/metrics.py +50 -0
- clsplusplus-7.2.3/src/clsplusplus/middleware.py +612 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/models.py +54 -0
- clsplusplus-7.2.3/src/clsplusplus/namespace_resolver.py +135 -0
- clsplusplus-7.2.3/src/clsplusplus/pricing.py +284 -0
- clsplusplus-7.2.3/src/clsplusplus/pricing_models.py +204 -0
- clsplusplus-7.2.3/src/clsplusplus/pricing_store.py +209 -0
- clsplusplus-7.2.3/src/clsplusplus/prompt_log.py +284 -0
- clsplusplus-7.2.3/src/clsplusplus/rate_limit.py +112 -0
- clsplusplus-7.2.3/src/clsplusplus/razorpay_service.py +392 -0
- clsplusplus-7.2.3/src/clsplusplus/resilience.py +430 -0
- clsplusplus-7.2.3/src/clsplusplus/stores/chat_session_store.py +167 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/stores/integration_store.py +91 -2
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/stores/l0_working_buffer.py +3 -0
- clsplusplus-7.2.3/src/clsplusplus/stores/user_store.py +771 -0
- clsplusplus-7.2.3/src/clsplusplus/stores/waitlist_store.py +259 -0
- clsplusplus-7.2.3/src/clsplusplus/stores/web_events_store.py +218 -0
- clsplusplus-7.2.3/src/clsplusplus/subscription_watchdog.py +118 -0
- clsplusplus-7.2.3/src/clsplusplus/tier_resolver.py +127 -0
- clsplusplus-7.2.3/src/clsplusplus/tiers.py +188 -0
- clsplusplus-7.2.3/src/clsplusplus/topical_resonance.py +503 -0
- clsplusplus-7.2.3/src/clsplusplus/usage.py +231 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/user_embeddings.py +4 -1
- clsplusplus-7.2.3/src/clsplusplus/user_pulse.py +233 -0
- clsplusplus-7.2.3/src/clsplusplus/user_service.py +670 -0
- clsplusplus-7.2.3/src/clsplusplus/waitlist_service.py +489 -0
- clsplusplus-7.2.3/src/clsplusplus/weblab.py +103 -0
- clsplusplus-7.2.3/src/clsplusplus/weblab_watcher.py +158 -0
- clsplusplus-7.2.3/src/clsplusplus/window_limits.py +151 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus.egg-info/PKG-INFO +91 -17
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus.egg-info/SOURCES.txt +75 -1
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus.egg-info/requires.txt +3 -0
- clsplusplus-7.2.3/tests/test_abuse_guard.py +465 -0
- clsplusplus-7.2.3/tests/test_admin_seed.py +40 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_api.py +4 -1
- clsplusplus-7.2.3/tests/test_api_usage_analytics.py +270 -0
- clsplusplus-7.2.3/tests/test_auth_me_api_key.py +198 -0
- clsplusplus-7.2.3/tests/test_billing_e2e.py +220 -0
- clsplusplus-7.2.3/tests/test_burst_hardening.py +296 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_config.py +6 -1
- clsplusplus-7.2.3/tests/test_cost_forecast.py +201 -0
- clsplusplus-7.2.3/tests/test_cross_llm_memory.py +537 -0
- clsplusplus-7.2.3/tests/test_debug_console.py +79 -0
- clsplusplus-7.2.3/tests/test_extension_integration.py +459 -0
- clsplusplus-7.2.3/tests/test_extension_ui.py +699 -0
- clsplusplus-7.2.3/tests/test_feedback_github.py +90 -0
- clsplusplus-7.2.3/tests/test_free_tier_lifecycle.py +270 -0
- clsplusplus-7.2.3/tests/test_full_api_coverage.py +489 -0
- clsplusplus-7.2.3/tests/test_funnel_metrics.py +315 -0
- clsplusplus-7.2.3/tests/test_geo_gating.py +210 -0
- clsplusplus-7.2.3/tests/test_health_metrics.py +226 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_integration_service.py +181 -0
- clsplusplus-7.2.3/tests/test_mcp_connect.py +168 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_memory_phase.py +9 -2
- clsplusplus-7.2.3/tests/test_memory_write_no_schema_garbage.py +94 -0
- clsplusplus-7.2.3/tests/test_metering_v2_healthcheck.py +378 -0
- clsplusplus-7.2.3/tests/test_metering_v2_notifier.py +198 -0
- clsplusplus-7.2.3/tests/test_metering_v2_pricing.py +186 -0
- clsplusplus-7.2.3/tests/test_metering_v2_reconciler.py +277 -0
- clsplusplus-7.2.3/tests/test_metering_v2_schema.py +203 -0
- clsplusplus-7.2.3/tests/test_metering_v2_writer.py +257 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_middleware.py +5 -4
- clsplusplus-7.2.3/tests/test_overage_billing.py +267 -0
- clsplusplus-7.2.3/tests/test_pricing.py +327 -0
- clsplusplus-7.2.3/tests/test_razorpay_billing.py +389 -0
- clsplusplus-7.2.3/tests/test_razorpay_subscription_webhooks.py +283 -0
- clsplusplus-7.2.3/tests/test_resilience.py +367 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_security.py +6 -4
- clsplusplus-7.2.3/tests/test_subscription_watchdog.py +161 -0
- clsplusplus-7.2.3/tests/test_tier_resolver.py +174 -0
- clsplusplus-7.2.3/tests/test_tiers.py +375 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_usage.py +74 -1
- clsplusplus-7.2.3/tests/test_user_auth.py +764 -0
- clsplusplus-7.2.3/tests/test_user_pulse.py +424 -0
- clsplusplus-7.2.3/tests/test_user_stories.py +380 -0
- clsplusplus-7.2.3/tests/test_waitlist.py +822 -0
- clsplusplus-7.2.3/tests/test_weblab.py +201 -0
- clsplusplus-7.2.3/tests/test_window_limits.py +386 -0
- clsplusplus-4.0.2/src/clsplusplus/api.py +0 -1596
- clsplusplus-4.0.2/src/clsplusplus/config.py +0 -116
- clsplusplus-4.0.2/src/clsplusplus/main.py +0 -21
- clsplusplus-4.0.2/src/clsplusplus/middleware.py +0 -325
- clsplusplus-4.0.2/src/clsplusplus/rate_limit.py +0 -53
- clsplusplus-4.0.2/src/clsplusplus/stores/user_store.py +0 -255
- clsplusplus-4.0.2/src/clsplusplus/tiers.py +0 -109
- clsplusplus-4.0.2/src/clsplusplus/usage.py +0 -130
- clsplusplus-4.0.2/src/clsplusplus/user_service.py +0 -256
- clsplusplus-4.0.2/tests/test_tiers.py +0 -211
- clsplusplus-4.0.2/tests/test_user_auth.py +0 -292
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/LICENSE +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/setup.cfg +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/auth.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/cli.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/client.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/cost_model.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/demo_llm.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/demo_local.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/embeddings.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/idempotency.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/jwt_utils.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/memory_cycle.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/memory_service.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/permissions.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/plasticity.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/rbac_service.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/reconsolidation.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/sleep_cycle.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/stores/__init__.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/stores/base.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/stores/l1_indexing_store.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/stores/l2_schema_graph.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/stores/l3_deep_recess.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/stores/l3_postgres.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/stores/rbac_store.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/stripe_service.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/temporal.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/test_suite.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/tracer.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus/webhook_dispatcher.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus.egg-info/dependency_links.txt +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus.egg-info/entry_points.txt +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/src/clsplusplus.egg-info/top_level.txt +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_admin.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_api_comprehensive.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_api_endpoints.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_auth.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_client_sdk.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_demo_llm.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_embeddings.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_idempotency.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_memory_cycle.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_memory_service.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_models.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_performance.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_plasticity.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_prototype_e2e.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_rate_limit.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_reconsolidation.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_regression.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_sleep_cycle.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_stores.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_user_embeddings.py +0 -0
- {clsplusplus-4.0.2 → clsplusplus-7.2.3}/tests/test_webhook_dispatcher.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: clsplusplus
|
|
3
|
-
Version:
|
|
3
|
+
Version: 7.2.3
|
|
4
4
|
Summary: Brain-inspired, model-agnostic persistent memory for LLMs. Learn, recall, forget — like a brain. Works with OpenAI, Claude, Gemini, Llama.
|
|
5
5
|
Author-email: AlphaForge AI Labs <contact@alphaforge.ai>
|
|
6
6
|
Maintainer-email: Rajamohan Jabbala <contact@alphaforge.ai>
|
|
@@ -48,14 +48,17 @@ Requires-Dist: apscheduler>=3.10.0; extra == "server"
|
|
|
48
48
|
Requires-Dist: PyJWT>=2.8.0; extra == "server"
|
|
49
49
|
Requires-Dist: bcrypt>=4.1.0; extra == "server"
|
|
50
50
|
Requires-Dist: stripe>=7.0.0; extra == "server"
|
|
51
|
+
Requires-Dist: razorpay>=1.4.0; extra == "server"
|
|
51
52
|
Requires-Dist: minio>=7.2.0; extra == "server"
|
|
52
53
|
Requires-Dist: pyarrow>=14.0.0; extra == "server"
|
|
54
|
+
Requires-Dist: posthog>=3.5.0; extra == "server"
|
|
53
55
|
Provides-Extra: dev
|
|
54
56
|
Requires-Dist: pytest>=7.4.0; extra == "dev"
|
|
55
57
|
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
|
|
56
58
|
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
|
|
57
59
|
Requires-Dist: pytest-timeout>=2.2.0; extra == "dev"
|
|
58
60
|
Requires-Dist: httpx>=0.26.0; extra == "dev"
|
|
61
|
+
Requires-Dist: locust>=2.20.0; extra == "dev"
|
|
59
62
|
Dynamic: license-file
|
|
60
63
|
|
|
61
64
|
<p align="center">
|
|
@@ -79,7 +82,7 @@ Dynamic: license-file
|
|
|
79
82
|
<a href="https://pypi.org/project/clsplusplus/"><img src="https://img.shields.io/pypi/v/clsplusplus?style=flat-square&label=PyPI&color=6366f1" alt="PyPI" /></a>
|
|
80
83
|
<a href="https://www.npmjs.com/package/clsplusplus"><img src="https://img.shields.io/npm/v/clsplusplus?style=flat-square&label=npm&color=cb3837" alt="npm" /></a>
|
|
81
84
|
<a href="https://pypi.org/project/clsplusplus/"><img src="https://img.shields.io/pypi/pyversions/clsplusplus?style=flat-square" alt="Python" /></a>
|
|
82
|
-
<a href="https://www.clsplusplus.com/docs"><img src="https://img.shields.io/badge/API-Live-22c55e?style=flat-square" alt="API" /></a>
|
|
85
|
+
<a href="https://www.clsplusplus.com/docs"><img src="https://img.shields.io/badge/API-Live%20at%20www.clsplusplus.com-22c55e?style=flat-square" alt="API" /></a>
|
|
83
86
|
<a href="https://github.com/rajamohan1950/CLSplusplus/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-Apache%202.0-blue?style=flat-square" alt="License" /></a>
|
|
84
87
|
<a href="https://github.com/rajamohan1950/CLSplusplus"><img src="https://img.shields.io/badge/Patent-Oct%202025-blue?style=flat-square" alt="Patent" /></a>
|
|
85
88
|
</p>
|
|
@@ -199,28 +202,49 @@ uvicorn clsplusplus.api:create_app --factory --host 0.0.0.0 --port 8080
|
|
|
199
202
|
|
|
200
203
|
## Try It Live
|
|
201
204
|
|
|
202
|
-
**[Try the demo](https://clsplusplus.
|
|
205
|
+
**[Try the demo](https://www.clsplusplus.com)** — Tell Claude something, ask OpenAI. Same memory. No sign-up.
|
|
206
|
+
|
|
207
|
+
The Chrome extension (Web Store, v6.0.1) captures user messages from
|
|
208
|
+
ChatGPT, Claude, and Gemini chat pages automatically and feeds them through
|
|
209
|
+
the same memory pipeline. Host permissions: `chatgpt.com`,
|
|
210
|
+
`chat.openai.com`, `claude.ai`, `gemini.google.com`. The Link Account popup
|
|
211
|
+
differentiates 401 / 403 / network / unknown errors so you know whether the
|
|
212
|
+
key is wrong, the account is unlinked, or the server is unreachable.
|
|
203
213
|
|
|
204
214
|
---
|
|
205
215
|
|
|
206
216
|
## Architecture
|
|
207
217
|
|
|
208
218
|
```
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
│
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
219
|
+
Browser (extension/capture.js) Any LLM client (SDK / REST)
|
|
220
|
+
↓ ↓
|
|
221
|
+
↓ www.clsplusplus.com (Vercel, Next.js)
|
|
222
|
+
↓ │ rewrites /api/v1/*, /api/admin/*
|
|
223
|
+
↓ ▼
|
|
224
|
+
└──────────────► Render-hosted FastAPI (clsplusplus-api)
|
|
225
|
+
│ middleware: auth, rate limit, abuse-guard
|
|
226
|
+
▼
|
|
227
|
+
┌─────────────────────────────────────────┐
|
|
228
|
+
│ CLS++ Core Service │
|
|
229
|
+
│ L0: Redis working buffer │ ← Prefrontal cortex
|
|
230
|
+
│ L1: PostgreSQL+pgvector episodic │ ← Hippocampus
|
|
231
|
+
│ L2: Schema graph (crystallized) │ ← Neocortex
|
|
232
|
+
│ L3: Deep archive │ ← Thalamus
|
|
233
|
+
│ PhaseMemoryEngine (gas→liquid→ │
|
|
234
|
+
│ solid→glass, auto tier-compression) │
|
|
235
|
+
│ SleepOrchestrator (replay + REM) │
|
|
236
|
+
│ ReconsolidationGate (belief revision) │
|
|
237
|
+
│ Weblab (PostHog flags + auto-rollback)│
|
|
238
|
+
│ Pricing control plane (memory-stored) │
|
|
239
|
+
└─────────────────────────────────────────┘
|
|
222
240
|
```
|
|
223
241
|
|
|
242
|
+
Every user message captured in the extension and every SDK `learn()` call
|
|
243
|
+
lands in L0, is promoted through the phase engine by the same thermodynamic
|
|
244
|
+
rules, and is persisted to L1 in the background. There is no separate
|
|
245
|
+
"explicit store" path — capture is continuous, tier compression is
|
|
246
|
+
automatic.
|
|
247
|
+
|
|
224
248
|
---
|
|
225
249
|
|
|
226
250
|
## SaaS Mode (Memory-as-a-Service)
|
|
@@ -232,10 +256,29 @@ export CLS_API_KEYS=cls_live_xxxxxxxxxxxxxxxxxxxxxxxx
|
|
|
232
256
|
export CLS_REQUIRE_API_KEY=true
|
|
233
257
|
export CLS_RATE_LIMIT_REQUESTS=100
|
|
234
258
|
export CLS_RATE_LIMIT_WINDOW_SECONDS=60
|
|
259
|
+
|
|
260
|
+
# Abuse-guard (env-tunable; defaults shown)
|
|
261
|
+
export CLS_ABUSE_AUTHFAIL_THRESHOLD=60 # auth failures per IP per window
|
|
262
|
+
export CLS_ABUSE_AUTHFAIL_WINDOW_SECONDS=600 # 10 minutes
|
|
263
|
+
export CLS_ABUSE_WHITELIST_IPS= # comma-separated operator IPs
|
|
235
264
|
```
|
|
236
265
|
|
|
266
|
+
Requests carrying a valid API key are exempt from auth-fail flood counting
|
|
267
|
+
(see `src/clsplusplus/abuse_guard.py`).
|
|
268
|
+
|
|
237
269
|
Product endpoints: `POST /v1/memories/encode`, `POST /v1/memories/retrieve`, `DELETE /v1/memories/forget`, `GET /v1/health/score`. See [SaaS docs](docs/SAAS_MEMORY_AS_SERVICE.md).
|
|
238
270
|
|
|
271
|
+
### Pricing
|
|
272
|
+
|
|
273
|
+
CLS++ launched in India and bills in **INR via Razorpay (UPI / QR)** — not
|
|
274
|
+
USD, not Stripe. Tiers: **Pro ₹299**, **Business ₹999**, **Enterprise
|
|
275
|
+
₹4,999**. The pricing control plane lives inside the CLS++ memory layer
|
|
276
|
+
itself (reserved namespace `__cls_pricing__`) and is operator-tunable at
|
|
277
|
+
runtime via `POST /admin/pricing/config`. The default config — currency,
|
|
278
|
+
margin floor/target, infra spend, dynamic-demand toggle — is seeded by
|
|
279
|
+
`src/clsplusplus/pricing_store.py` on first read. `GET /v1/pricing` is a
|
|
280
|
+
public, abuse-exempt endpoint.
|
|
281
|
+
|
|
239
282
|
---
|
|
240
283
|
|
|
241
284
|
## Deployment
|
|
@@ -268,11 +311,42 @@ Product endpoints: `POST /v1/memories/encode`, `POST /v1/memories/retrieve`, `DE
|
|
|
268
311
|
|
|
269
312
|
- [x] Four stores (L0–L3) + Plasticity Engine
|
|
270
313
|
- [x] Write/Read API + Python SDK
|
|
271
|
-
- [x] Docker Compose + Render deploy
|
|
314
|
+
- [x] Docker Compose + Render deploy (Dockerfile ships `/app/scripts/` for operator tooling)
|
|
272
315
|
- [x] Sleep cycle orchestrator
|
|
273
316
|
- [x] Reconsolidation gate
|
|
274
317
|
- [x] API key auth + rate limiting
|
|
275
318
|
- [x] SaaS product endpoints
|
|
319
|
+
- [x] Chrome extension (v6.0.1) capturing ChatGPT / Claude / Gemini
|
|
320
|
+
- [x] Abuse-guard with env-tunable thresholds and operator IP whitelist
|
|
321
|
+
- [x] PostHog Weblab — staged rollouts with auto-rollback (5xx > 2% or p95 > 3s)
|
|
322
|
+
- [x] INR pricing (Razorpay / UPI) with memory-resident control plane
|
|
323
|
+
|
|
324
|
+
## Recent Architectural Decisions
|
|
325
|
+
|
|
326
|
+
- **Auto-crystallization gated OFF by default.** The Landauer
|
|
327
|
+
liquid→solid pipeline produced low-quality `[Schema: subject]` token-soup
|
|
328
|
+
entries that leaked into user-visible memory lists. Re-enable per process
|
|
329
|
+
with `CLS_ENABLE_AUTO_CRYSTALLIZATION=1`. Melting still runs so existing
|
|
330
|
+
schemas drain out. See `src/clsplusplus/memory_phase.py`.
|
|
331
|
+
- **Pricing lives in the memory layer.** Operator-tunable config (margin
|
|
332
|
+
floor/target, infra cost, dynamic-demand toggle) and the bucketed demand
|
|
333
|
+
history are stored as two fixed-id documents in namespace
|
|
334
|
+
`__cls_pricing__`, not in env vars.
|
|
335
|
+
- **Frontend ↔ backend topology.** The Next.js frontend on Vercel
|
|
336
|
+
(`www.clsplusplus.com`) rewrites `/api/v1/*` and `/api/admin/*` to the
|
|
337
|
+
Render-hosted FastAPI. The bare onrender.com host is the internal
|
|
338
|
+
upstream target — not the public surface.
|
|
339
|
+
- **Integration ownership.** `POST /v1/integrations` injects
|
|
340
|
+
`owner_email` from the JWT-authed user; non-admin override returns 403.
|
|
341
|
+
A backfill script handles legacy NULL rows.
|
|
342
|
+
|
|
343
|
+
## Operator Runbooks
|
|
344
|
+
|
|
345
|
+
See [docs/RUNBOOKS.md](docs/RUNBOOKS.md) and
|
|
346
|
+
[docs/LAUNCH_RUNBOOK.md](docs/LAUNCH_RUNBOOK.md) for incident response,
|
|
347
|
+
deploy procedures, and the abuse-guard / weblab dashboards. The
|
|
348
|
+
container ships operator scripts at `/app/scripts/` (see
|
|
349
|
+
`scripts/admin_doctor.py`, `scripts/backfill_integration_owner_email.py`).
|
|
276
350
|
|
|
277
351
|
---
|
|
278
352
|
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
<a href="https://pypi.org/project/clsplusplus/"><img src="https://img.shields.io/pypi/v/clsplusplus?style=flat-square&label=PyPI&color=6366f1" alt="PyPI" /></a>
|
|
20
20
|
<a href="https://www.npmjs.com/package/clsplusplus"><img src="https://img.shields.io/npm/v/clsplusplus?style=flat-square&label=npm&color=cb3837" alt="npm" /></a>
|
|
21
21
|
<a href="https://pypi.org/project/clsplusplus/"><img src="https://img.shields.io/pypi/pyversions/clsplusplus?style=flat-square" alt="Python" /></a>
|
|
22
|
-
<a href="https://www.clsplusplus.com/docs"><img src="https://img.shields.io/badge/API-Live-22c55e?style=flat-square" alt="API" /></a>
|
|
22
|
+
<a href="https://www.clsplusplus.com/docs"><img src="https://img.shields.io/badge/API-Live%20at%20www.clsplusplus.com-22c55e?style=flat-square" alt="API" /></a>
|
|
23
23
|
<a href="https://github.com/rajamohan1950/CLSplusplus/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-Apache%202.0-blue?style=flat-square" alt="License" /></a>
|
|
24
24
|
<a href="https://github.com/rajamohan1950/CLSplusplus"><img src="https://img.shields.io/badge/Patent-Oct%202025-blue?style=flat-square" alt="Patent" /></a>
|
|
25
25
|
</p>
|
|
@@ -139,28 +139,49 @@ uvicorn clsplusplus.api:create_app --factory --host 0.0.0.0 --port 8080
|
|
|
139
139
|
|
|
140
140
|
## Try It Live
|
|
141
141
|
|
|
142
|
-
**[Try the demo](https://clsplusplus.
|
|
142
|
+
**[Try the demo](https://www.clsplusplus.com)** — Tell Claude something, ask OpenAI. Same memory. No sign-up.
|
|
143
|
+
|
|
144
|
+
The Chrome extension (Web Store, v6.0.1) captures user messages from
|
|
145
|
+
ChatGPT, Claude, and Gemini chat pages automatically and feeds them through
|
|
146
|
+
the same memory pipeline. Host permissions: `chatgpt.com`,
|
|
147
|
+
`chat.openai.com`, `claude.ai`, `gemini.google.com`. The Link Account popup
|
|
148
|
+
differentiates 401 / 403 / network / unknown errors so you know whether the
|
|
149
|
+
key is wrong, the account is unlinked, or the server is unreachable.
|
|
143
150
|
|
|
144
151
|
---
|
|
145
152
|
|
|
146
153
|
## Architecture
|
|
147
154
|
|
|
148
155
|
```
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
│
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
156
|
+
Browser (extension/capture.js) Any LLM client (SDK / REST)
|
|
157
|
+
↓ ↓
|
|
158
|
+
↓ www.clsplusplus.com (Vercel, Next.js)
|
|
159
|
+
↓ │ rewrites /api/v1/*, /api/admin/*
|
|
160
|
+
↓ ▼
|
|
161
|
+
└──────────────► Render-hosted FastAPI (clsplusplus-api)
|
|
162
|
+
│ middleware: auth, rate limit, abuse-guard
|
|
163
|
+
▼
|
|
164
|
+
┌─────────────────────────────────────────┐
|
|
165
|
+
│ CLS++ Core Service │
|
|
166
|
+
│ L0: Redis working buffer │ ← Prefrontal cortex
|
|
167
|
+
│ L1: PostgreSQL+pgvector episodic │ ← Hippocampus
|
|
168
|
+
│ L2: Schema graph (crystallized) │ ← Neocortex
|
|
169
|
+
│ L3: Deep archive │ ← Thalamus
|
|
170
|
+
│ PhaseMemoryEngine (gas→liquid→ │
|
|
171
|
+
│ solid→glass, auto tier-compression) │
|
|
172
|
+
│ SleepOrchestrator (replay + REM) │
|
|
173
|
+
│ ReconsolidationGate (belief revision) │
|
|
174
|
+
│ Weblab (PostHog flags + auto-rollback)│
|
|
175
|
+
│ Pricing control plane (memory-stored) │
|
|
176
|
+
└─────────────────────────────────────────┘
|
|
162
177
|
```
|
|
163
178
|
|
|
179
|
+
Every user message captured in the extension and every SDK `learn()` call
|
|
180
|
+
lands in L0, is promoted through the phase engine by the same thermodynamic
|
|
181
|
+
rules, and is persisted to L1 in the background. There is no separate
|
|
182
|
+
"explicit store" path — capture is continuous, tier compression is
|
|
183
|
+
automatic.
|
|
184
|
+
|
|
164
185
|
---
|
|
165
186
|
|
|
166
187
|
## SaaS Mode (Memory-as-a-Service)
|
|
@@ -172,10 +193,29 @@ export CLS_API_KEYS=cls_live_xxxxxxxxxxxxxxxxxxxxxxxx
|
|
|
172
193
|
export CLS_REQUIRE_API_KEY=true
|
|
173
194
|
export CLS_RATE_LIMIT_REQUESTS=100
|
|
174
195
|
export CLS_RATE_LIMIT_WINDOW_SECONDS=60
|
|
196
|
+
|
|
197
|
+
# Abuse-guard (env-tunable; defaults shown)
|
|
198
|
+
export CLS_ABUSE_AUTHFAIL_THRESHOLD=60 # auth failures per IP per window
|
|
199
|
+
export CLS_ABUSE_AUTHFAIL_WINDOW_SECONDS=600 # 10 minutes
|
|
200
|
+
export CLS_ABUSE_WHITELIST_IPS= # comma-separated operator IPs
|
|
175
201
|
```
|
|
176
202
|
|
|
203
|
+
Requests carrying a valid API key are exempt from auth-fail flood counting
|
|
204
|
+
(see `src/clsplusplus/abuse_guard.py`).
|
|
205
|
+
|
|
177
206
|
Product endpoints: `POST /v1/memories/encode`, `POST /v1/memories/retrieve`, `DELETE /v1/memories/forget`, `GET /v1/health/score`. See [SaaS docs](docs/SAAS_MEMORY_AS_SERVICE.md).
|
|
178
207
|
|
|
208
|
+
### Pricing
|
|
209
|
+
|
|
210
|
+
CLS++ launched in India and bills in **INR via Razorpay (UPI / QR)** — not
|
|
211
|
+
USD, not Stripe. Tiers: **Pro ₹299**, **Business ₹999**, **Enterprise
|
|
212
|
+
₹4,999**. The pricing control plane lives inside the CLS++ memory layer
|
|
213
|
+
itself (reserved namespace `__cls_pricing__`) and is operator-tunable at
|
|
214
|
+
runtime via `POST /admin/pricing/config`. The default config — currency,
|
|
215
|
+
margin floor/target, infra spend, dynamic-demand toggle — is seeded by
|
|
216
|
+
`src/clsplusplus/pricing_store.py` on first read. `GET /v1/pricing` is a
|
|
217
|
+
public, abuse-exempt endpoint.
|
|
218
|
+
|
|
179
219
|
---
|
|
180
220
|
|
|
181
221
|
## Deployment
|
|
@@ -208,11 +248,42 @@ Product endpoints: `POST /v1/memories/encode`, `POST /v1/memories/retrieve`, `DE
|
|
|
208
248
|
|
|
209
249
|
- [x] Four stores (L0–L3) + Plasticity Engine
|
|
210
250
|
- [x] Write/Read API + Python SDK
|
|
211
|
-
- [x] Docker Compose + Render deploy
|
|
251
|
+
- [x] Docker Compose + Render deploy (Dockerfile ships `/app/scripts/` for operator tooling)
|
|
212
252
|
- [x] Sleep cycle orchestrator
|
|
213
253
|
- [x] Reconsolidation gate
|
|
214
254
|
- [x] API key auth + rate limiting
|
|
215
255
|
- [x] SaaS product endpoints
|
|
256
|
+
- [x] Chrome extension (v6.0.1) capturing ChatGPT / Claude / Gemini
|
|
257
|
+
- [x] Abuse-guard with env-tunable thresholds and operator IP whitelist
|
|
258
|
+
- [x] PostHog Weblab — staged rollouts with auto-rollback (5xx > 2% or p95 > 3s)
|
|
259
|
+
- [x] INR pricing (Razorpay / UPI) with memory-resident control plane
|
|
260
|
+
|
|
261
|
+
## Recent Architectural Decisions
|
|
262
|
+
|
|
263
|
+
- **Auto-crystallization gated OFF by default.** The Landauer
|
|
264
|
+
liquid→solid pipeline produced low-quality `[Schema: subject]` token-soup
|
|
265
|
+
entries that leaked into user-visible memory lists. Re-enable per process
|
|
266
|
+
with `CLS_ENABLE_AUTO_CRYSTALLIZATION=1`. Melting still runs so existing
|
|
267
|
+
schemas drain out. See `src/clsplusplus/memory_phase.py`.
|
|
268
|
+
- **Pricing lives in the memory layer.** Operator-tunable config (margin
|
|
269
|
+
floor/target, infra cost, dynamic-demand toggle) and the bucketed demand
|
|
270
|
+
history are stored as two fixed-id documents in namespace
|
|
271
|
+
`__cls_pricing__`, not in env vars.
|
|
272
|
+
- **Frontend ↔ backend topology.** The Next.js frontend on Vercel
|
|
273
|
+
(`www.clsplusplus.com`) rewrites `/api/v1/*` and `/api/admin/*` to the
|
|
274
|
+
Render-hosted FastAPI. The bare onrender.com host is the internal
|
|
275
|
+
upstream target — not the public surface.
|
|
276
|
+
- **Integration ownership.** `POST /v1/integrations` injects
|
|
277
|
+
`owner_email` from the JWT-authed user; non-admin override returns 403.
|
|
278
|
+
A backfill script handles legacy NULL rows.
|
|
279
|
+
|
|
280
|
+
## Operator Runbooks
|
|
281
|
+
|
|
282
|
+
See [docs/RUNBOOKS.md](docs/RUNBOOKS.md) and
|
|
283
|
+
[docs/LAUNCH_RUNBOOK.md](docs/LAUNCH_RUNBOOK.md) for incident response,
|
|
284
|
+
deploy procedures, and the abuse-guard / weblab dashboards. The
|
|
285
|
+
container ships operator scripts at `/app/scripts/` (see
|
|
286
|
+
`scripts/admin_doctor.py`, `scripts/backfill_integration_owner_email.py`).
|
|
216
287
|
|
|
217
288
|
---
|
|
218
289
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "clsplusplus"
|
|
7
|
-
version = "
|
|
7
|
+
version = "7.2.3"
|
|
8
8
|
description = "Brain-inspired, model-agnostic persistent memory for LLMs. Learn, recall, forget — like a brain. Works with OpenAI, Claude, Gemini, Llama."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -58,8 +58,10 @@ server = [
|
|
|
58
58
|
"PyJWT>=2.8.0",
|
|
59
59
|
"bcrypt>=4.1.0",
|
|
60
60
|
"stripe>=7.0.0",
|
|
61
|
+
"razorpay>=1.4.0",
|
|
61
62
|
"minio>=7.2.0",
|
|
62
63
|
"pyarrow>=14.0.0",
|
|
64
|
+
"posthog>=3.5.0",
|
|
63
65
|
]
|
|
64
66
|
dev = [
|
|
65
67
|
"pytest>=7.4.0",
|
|
@@ -67,6 +69,7 @@ dev = [
|
|
|
67
69
|
"pytest-cov>=4.1.0",
|
|
68
70
|
"pytest-timeout>=2.2.0",
|
|
69
71
|
"httpx>=0.26.0",
|
|
72
|
+
"locust>=2.20.0",
|
|
70
73
|
]
|
|
71
74
|
|
|
72
75
|
[project.scripts]
|
|
@@ -89,8 +92,22 @@ where = ["src"]
|
|
|
89
92
|
asyncio_mode = "auto"
|
|
90
93
|
testpaths = ["tests"]
|
|
91
94
|
pythonpath = ["src"]
|
|
95
|
+
# Test category markers — every new test should carry at least one.
|
|
96
|
+
# The old suite (tests/test_*.py) is implicitly "unit" unless otherwise marked.
|
|
92
97
|
markers = [
|
|
93
|
-
"slow:
|
|
98
|
+
"slow: long-running tests — excluded from default run",
|
|
99
|
+
"unit: pure function/module tests, no network, no database",
|
|
100
|
+
"regression: guards against specific previously-fixed bugs",
|
|
101
|
+
"functional: end-to-end against a running API + Postgres + Redis",
|
|
102
|
+
"smoke: minimal liveness checks — server up, basic routes respond",
|
|
103
|
+
"sanity: shallow correctness checks on critical contracts",
|
|
104
|
+
"performance: measures latency/throughput with assertions on bounds",
|
|
105
|
+
"load: sustained high concurrency over time",
|
|
106
|
+
"stress: pushes beyond expected capacity to find breaking point",
|
|
107
|
+
"dip: sustained-load ramp-down test; looks for leak / degradation",
|
|
108
|
+
"whitebox: uses internal module imports and private state",
|
|
109
|
+
"blackbox: exercises only the public HTTP surface",
|
|
110
|
+
"beta: curated user-journey scenarios that mimic real customer use",
|
|
94
111
|
]
|
|
95
112
|
filterwarnings = [
|
|
96
113
|
"ignore::DeprecationWarning",
|