compresh-mcp 0.2.2__tar.gz → 0.2.4__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 (37) hide show
  1. {compresh_mcp-0.2.2/src/compresh_mcp.egg-info → compresh_mcp-0.2.4}/PKG-INFO +1 -1
  2. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/pyproject.toml +1 -1
  3. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp/__init__.py +1 -1
  4. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp/auth.py +8 -0
  5. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp/server.py +54 -8
  6. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4/src/compresh_mcp.egg-info}/PKG-INFO +1 -1
  7. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/tests/test_smoke.py +7 -1
  8. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/LICENSE +0 -0
  9. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/NOTICES.md +0 -0
  10. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/README.md +0 -0
  11. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/setup.cfg +0 -0
  12. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp/onboarding.py +0 -0
  13. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp/tul1_client.py +0 -0
  14. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp/tulbase/__init__.py +0 -0
  15. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp/tulbase/backfill.py +0 -0
  16. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp/tulbase/cli.py +0 -0
  17. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp/tulbase/cold_storage.py +0 -0
  18. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp/tulbase/compose.py +0 -0
  19. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp/tulbase/compression_log.py +0 -0
  20. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp/tulbase/config.py +0 -0
  21. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp/tulbase/counter.py +0 -0
  22. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp/tulbase/injection.py +0 -0
  23. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp/tulbase/main.py +0 -0
  24. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp/tulbase/modality.py +0 -0
  25. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp/tulbase/pipeline.py +0 -0
  26. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp/tulbase/provenance.py +0 -0
  27. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp/tulbase/retrieval.py +0 -0
  28. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp/tulbase/router.py +0 -0
  29. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp/tulbase/summarizer.py +0 -0
  30. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp/tulbase/system_prompts.py +0 -0
  31. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp/tulbase/tools.py +0 -0
  32. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp/tulbase/turn_box.py +0 -0
  33. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp.egg-info/SOURCES.txt +0 -0
  34. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp.egg-info/dependency_links.txt +0 -0
  35. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp.egg-info/entry_points.txt +0 -0
  36. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp.egg-info/requires.txt +0 -0
  37. {compresh_mcp-0.2.2 → compresh_mcp-0.2.4}/src/compresh_mcp.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: compresh-mcp
3
- Version: 0.2.2
3
+ Version: 0.2.4
4
4
  Summary: MCP server for Compresh — production-grade context compression with Q-protective ranking, epistemic markers, and depth-aware adaptation
5
5
  Author-email: Compresh Ltd <hello@compre.sh>
6
6
  License: BUSL-1.1
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "compresh-mcp"
7
- version = "0.2.2"
7
+ version = "0.2.4"
8
8
  description = "MCP server for Compresh — production-grade context compression with Q-protective ranking, epistemic markers, and depth-aware adaptation"
9
9
  readme = "README.md"
10
10
  license = { text = "BUSL-1.1" }
@@ -39,7 +39,7 @@ Architecture history:
39
39
 
40
40
  from . import tulbase
41
41
 
42
- __version__ = "0.2.2"
42
+ __version__ = "0.2.4"
43
43
  __author__ = "Compresh Ltd"
44
44
  __license__ = "BUSL-1.1"
45
45
 
@@ -136,6 +136,8 @@ def report_usage(
136
136
  session_id: str,
137
137
  saved_input_tokens: int,
138
138
  saved_chars: int,
139
+ original_chars: int = 0,
140
+ tulbase_chars: int = 0,
139
141
  n_turns: int,
140
142
  n_compressed_entries: int,
141
143
  provider_hint: Optional[str] = None,
@@ -158,6 +160,12 @@ def report_usage(
158
160
  "session_id": session_id,
159
161
  "saved_input_tokens": saved_input_tokens,
160
162
  "saved_chars": saved_chars,
163
+ # Absolute sizes (#9a): server only sees the compressed context, so it
164
+ # needs the client-reported original size to compute total savings; it
165
+ # can measure tulbase size itself but we send it for cross-check + the
166
+ # free-user portal saving display (#14).
167
+ "original_chars": original_chars,
168
+ "tulbase_chars": tulbase_chars,
161
169
  "n_turns": n_turns,
162
170
  "n_compressed_entries": n_compressed_entries,
163
171
  "provider_hint": provider_hint,
@@ -127,10 +127,14 @@ class SessionState:
127
127
  self.log.ensure_schema()
128
128
  self.cold = ColdStorage(str(self.workdir / "cold"))
129
129
 
130
- # Local pipeline runs the open-source tulbase core only — no Q-protective
131
- # ranking, no epistemic markers, no semantic store. Those layers run on
132
- # the Compresh server (see ``tul1_client.call_v1_tul1``). Local pipeline
133
- # is still needed for cold storage + fetch_compressed retrieval support.
130
+ # Local pipeline runs the open-source tulbase core only — no Q matrix
131
+ # classifier, no Q-protective ranking, no epistemic markers, no semantic
132
+ # store. Those are the PAID layer and run server-side (see
133
+ # ``tul1_client.call_v1_tul1`` /v1/tul1). [21 May 2026: a client-side
134
+ # classifier was explored (Decision B) then REVERSED — no bench basis;
135
+ # the classifier is deterministic + cheap and the server already
136
+ # receives the full messages, so client-side classification offered no
137
+ # measurable gain.] Local pipeline still backs cold storage + fetch.
134
138
  self.pipeline = Pipeline(
135
139
  log=self.log,
136
140
  cold=self.cold,
@@ -317,6 +321,43 @@ async def tool_compress(
317
321
  len(b.compressed_refs) for b in turn_boxes[: local_composed.n_compressed]
318
322
  )
319
323
 
324
+ # Net-negative saving guard: on short conversations the Compresh memory
325
+ # header can outweigh the text it elides, so the "compressed" view is
326
+ # actually larger than the raw turns. Reporting that as a negative
327
+ # saving is wrong (it drags down dashboard totals and bills nothing).
328
+ # Treat it as a pass-through: applied=False, saving=0, raw messages
329
+ # returned unchanged. The calling hook then skips injection.
330
+ if saving_chars <= 0:
331
+ state.n_turns = max(state.n_turns, len(messages))
332
+ asyncio.create_task(
333
+ _report_usage_background(
334
+ session_id=session_id,
335
+ saved_input_tokens=0,
336
+ saved_chars=0,
337
+ original_chars=raw_chars,
338
+ tulbase_chars=optimized_chars,
339
+ n_turns=state.n_turns,
340
+ n_compressed_entries=0,
341
+ provider_hint=provider_hint,
342
+ model_hint=model_hint,
343
+ )
344
+ )
345
+ return {
346
+ "ok": True,
347
+ "applied": False,
348
+ "reason": "net_negative_saving",
349
+ "optimized_messages": messages,
350
+ "compresh_md": "",
351
+ "raw_tail": messages,
352
+ "n_compressed_turns": 0,
353
+ "n_compressed_entries": 0,
354
+ "n_total": len(messages),
355
+ "saving_chars": 0,
356
+ "session_id": session_id,
357
+ "protection_mode": protection_mode,
358
+ "tier": (get_auth().tier or "unknown"),
359
+ }
360
+
320
361
  state.saved_chars += saving_chars
321
362
  state.n_compressed_entries += n_compressed_entries
322
363
  state.n_turns = max(state.n_turns, len(messages))
@@ -342,6 +383,8 @@ async def tool_compress(
342
383
  session_id=session_id,
343
384
  saved_input_tokens=saving_chars // 4,
344
385
  saved_chars=saving_chars,
386
+ original_chars=raw_chars,
387
+ tulbase_chars=optimized_chars,
345
388
  n_turns=state.n_turns,
346
389
  n_compressed_entries=state.n_compressed_entries,
347
390
  provider_hint=provider_hint,
@@ -450,9 +493,12 @@ async def tool_stats(session_id: str) -> dict[str, Any]:
450
493
  "n_compressed_entries": state.n_compressed_entries,
451
494
  "saved_chars": state.saved_chars,
452
495
  "storage_path": str(state.workdir),
453
- "protect_mode_active": DEFAULT_TIER1_PROTECT_MODE,
454
- "q_classifier_enabled": True,
455
- "epi_classifier_enabled": True,
496
+ # Local pipeline = open-source tulbase core only (no Q-protective).
497
+ # Q-protective ranking + epistemic markers run server-side (/v1/tul1).
498
+ # Report the LOCAL pipeline's real state, not a hardcoded flag.
499
+ "protect_mode_active": getattr(state.pipeline.summarizer, "protect_mode", "off"),
500
+ "q_classifier_enabled": state.pipeline.q_classifier is not None,
501
+ "epi_classifier_enabled": getattr(state.pipeline.summarizer, "epi_classifier", None) is not None,
456
502
  }
457
503
 
458
504
 
@@ -680,7 +726,7 @@ async def serve() -> None:
680
726
  read_stream, write_stream,
681
727
  InitializationOptions(
682
728
  server_name="compresh-mcp",
683
- server_version="0.2.2",
729
+ server_version="0.2.4",
684
730
  capabilities=app.get_capabilities(
685
731
  notification_options=NotificationOptions(),
686
732
  experimental_capabilities={},
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: compresh-mcp
3
- Version: 0.2.2
3
+ Version: 0.2.4
4
4
  Summary: MCP server for Compresh — production-grade context compression with Q-protective ranking, epistemic markers, and depth-aware adaptation
5
5
  Author-email: Compresh Ltd <hello@compre.sh>
6
6
  License: BUSL-1.1
@@ -11,9 +11,15 @@ from __future__ import annotations
11
11
 
12
12
 
13
13
  def test_package_importable() -> None:
14
+ import re
15
+
14
16
  import compresh_mcp
15
17
 
16
- assert compresh_mcp.__version__ == "0.2.0"
18
+ # Assert a valid semver, not a hardcoded version: the old "0.2.0" check
19
+ # went stale and failed on every release bump (2026-05-21 fix).
20
+ assert re.fullmatch(r"\d+\.\d+\.\d+", compresh_mcp.__version__), (
21
+ f"unexpected version: {compresh_mcp.__version__!r}"
22
+ )
17
23
  assert compresh_mcp.__license__ == "BUSL-1.1"
18
24
 
19
25
 
File without changes
File without changes
File without changes
File without changes