leancontext 2.0.6__tar.gz → 2.0.7__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.
- {leancontext-2.0.6 → leancontext-2.0.7}/CHANGELOG.md +11 -1
- {leancontext-2.0.6 → leancontext-2.0.7}/PKG-INFO +1 -1
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/fidelity.py +23 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/pyproject.toml +1 -1
- {leancontext-2.0.6 → leancontext-2.0.7}/tests/test_fidelity.py +8 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/.editorconfig +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/.github/CODEOWNERS +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/.github/dependabot.yml +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/.github/workflows/ci.yml +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/.github/workflows/codeql.yml +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/.github/workflows/publish.yml +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/.gitignore +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/.pre-commit-config.yaml +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/AGENTS.md +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/CITATION.cff +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/CODE_OF_CONDUCT.md +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/CONTRIBUTING.md +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/LICENSE +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/README.md +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/RELEASING.md +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/SECURITY.md +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/SUPPORT.md +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/assets/logo.png +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/assets/logo.svg +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/bench.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/demo.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/docs/ARCHITECTURE.md +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/examples/basic_usage.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/examples/validate_caching.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/__init__.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/cli.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/core.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/cost.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/integrations/__init__.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/integrations/_common.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/integrations/anthropic_native.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/integrations/clients.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/integrations/decorator.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/integrations/frameworks.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/integrations/litellm.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/integrations/mcp_server.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/integrations/otel.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/integrations/proxy.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/messages.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/paging.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/py.typed +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/reducers/__init__.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/reducers/base.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/reducers/diff.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/reducers/html.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/reducers/json_data.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/reducers/logs.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/reducers/stacktrace.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/reducers/table.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/leancontext/tokens.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/tests/test_cache.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/tests/test_concurrency.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/tests/test_core.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/tests/test_differentiators.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/tests/test_frameworks.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/tests/test_gateway.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/tests/test_gemini.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/tests/test_limits.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/tests/test_mcp.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/tests/test_messages.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/tests/test_otel.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/tests/test_paging.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/tests/test_proxy.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/tests/test_reducers.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/tests/test_table.py +0 -0
- {leancontext-2.0.6 → leancontext-2.0.7}/tests/test_tokens.py +0 -0
|
@@ -5,6 +5,15 @@ All notable changes to this project are documented here. The format is based on
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [2.0.7] - 2026-06-21
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- HTML fidelity is now content-aware: it measures the fraction of the original's
|
|
12
|
+
visible-text words kept in the output (reusing the HTML reducer's own extractor),
|
|
13
|
+
so dropped body text lowers the score and trips the fidelity gate. The previous
|
|
14
|
+
salience-based check returned 1.0 for lost prose that contained no error keyword.
|
|
15
|
+
Correct strips still score ~1.0 and reduce as before.
|
|
16
|
+
|
|
8
17
|
## [2.0.6] - 2026-06-21
|
|
9
18
|
|
|
10
19
|
### Fixed
|
|
@@ -78,7 +87,8 @@ superseded by 2.0.2. Version 2.0.3 was never published.
|
|
|
78
87
|
- Targets Python 3.14; ruff, mypy, and coverage run in CI; examples, contributor, and
|
|
79
88
|
security docs included.
|
|
80
89
|
|
|
81
|
-
[Unreleased]: https://github.com/pankajniet/LeanContext/compare/v2.0.
|
|
90
|
+
[Unreleased]: https://github.com/pankajniet/LeanContext/compare/v2.0.7...HEAD
|
|
91
|
+
[2.0.7]: https://github.com/pankajniet/LeanContext/releases/tag/v2.0.7
|
|
82
92
|
[2.0.6]: https://github.com/pankajniet/LeanContext/releases/tag/v2.0.6
|
|
83
93
|
[2.0.5]: https://github.com/pankajniet/LeanContext/releases/tag/v2.0.5
|
|
84
94
|
[2.0.4]: https://github.com/pankajniet/LeanContext/releases/tag/v2.0.4
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: leancontext
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.7
|
|
4
4
|
Summary: Deterministic, type-aware reduction of agent tool outputs at the source. Cut LLM token cost without making the agent do less.
|
|
5
5
|
Project-URL: Homepage, https://github.com/pankajniet/LeanContext
|
|
6
6
|
Project-URL: Repository, https://github.com/pankajniet/LeanContext
|
|
@@ -103,10 +103,33 @@ def _stacktrace_fidelity(original: str, reduced: str) -> float:
|
|
|
103
103
|
return 1.0 if lines[-1] in reduced else 0.0
|
|
104
104
|
|
|
105
105
|
|
|
106
|
+
def _html_fidelity(original: str, reduced: str) -> float:
|
|
107
|
+
"""Fraction of the original's visible-text words preserved in the output.
|
|
108
|
+
|
|
109
|
+
Reuses the HTML reducer's own extractor, so the check measures exactly what the
|
|
110
|
+
reduction is supposed to keep (visible text, not tags/scripts). A correct strip
|
|
111
|
+
keeps every word and scores ~1.0; dropping body text drops the score — unlike a
|
|
112
|
+
generic salience check, which is blind to lost prose with no error keywords.
|
|
113
|
+
"""
|
|
114
|
+
from .reducers.html import _Extract # local import avoids an import cycle
|
|
115
|
+
|
|
116
|
+
parser = _Extract()
|
|
117
|
+
try:
|
|
118
|
+
parser.feed(original)
|
|
119
|
+
except Exception:
|
|
120
|
+
return 1.0
|
|
121
|
+
words = [w for part in parser.parts for w in part.split() if w]
|
|
122
|
+
if not words:
|
|
123
|
+
return 1.0
|
|
124
|
+
kept = sum(1 for w in words if w in reduced)
|
|
125
|
+
return kept / len(words)
|
|
126
|
+
|
|
127
|
+
|
|
106
128
|
_TYPED = {
|
|
107
129
|
"json": _json_fidelity,
|
|
108
130
|
"diff": _diff_fidelity,
|
|
109
131
|
"stacktrace": _stacktrace_fidelity,
|
|
132
|
+
"html": _html_fidelity,
|
|
110
133
|
}
|
|
111
134
|
|
|
112
135
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "leancontext"
|
|
3
|
-
version = "2.0.
|
|
3
|
+
version = "2.0.7"
|
|
4
4
|
description = "Deterministic, type-aware reduction of agent tool outputs at the source. Cut LLM token cost without making the agent do less."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
@@ -34,3 +34,11 @@ def test_stacktrace_fidelity_requires_exception():
|
|
|
34
34
|
def test_unknown_kind_uses_signal_score():
|
|
35
35
|
# no severity lines -> nothing critical -> 1.0
|
|
36
36
|
assert fidelity_score("just some plain text", "plain text", "text") == 1.0
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def test_html_fidelity_drops_when_visible_text_lost():
|
|
40
|
+
# neutral prose (no severity keyword): a content-aware check must still see the loss
|
|
41
|
+
html = "<html><body><h1>Welcome to the dashboard</h1><p>ordinary body paragraph</p></body></html>"
|
|
42
|
+
assert fidelity_score(html, "Welcome to the dashboard\n\nordinary body paragraph", "html") == 1.0
|
|
43
|
+
assert fidelity_score(html, "Welcome to the dashboard", "html") < 1.0 # body dropped
|
|
44
|
+
assert fidelity_score(html, "", "html") < 1.0
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|