commons 0.1.0.dev1__py3-none-any.whl
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.
- commons/__init__.py +8 -0
- commons/_citations.py +69 -0
- commons/_provenance.py +81 -0
- commons/py.typed +0 -0
- commons-0.1.0.dev1.dist-info/METADATA +31 -0
- commons-0.1.0.dev1.dist-info/RECORD +8 -0
- commons-0.1.0.dev1.dist-info/WHEEL +4 -0
- commons-0.1.0.dev1.dist-info/licenses/LICENSE.md +21 -0
commons/__init__.py
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"""Build trustworthy data agents.
|
|
2
|
+
|
|
3
|
+
Give an LLM data, semantic, and context layers to work with, tools for
|
|
4
|
+
querying them, and A/B/C provenance semantics so every answer carries a
|
|
5
|
+
classification as to how much it can be trusted.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
__all__: list[str] = []
|
commons/_citations.py
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"""Verifying a quoted citation against a trusted corpus.
|
|
2
|
+
|
|
3
|
+
The normalization rules and the matching verdicts are a cross-language contract
|
|
4
|
+
pinned by ``tests/shared/citations.json``; change that fixture, not just this
|
|
5
|
+
file. ``pkg-r/R/citations.R`` implements the same contract for R.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import re
|
|
11
|
+
from collections.abc import Sequence
|
|
12
|
+
from dataclasses import dataclass
|
|
13
|
+
from typing import Literal
|
|
14
|
+
|
|
15
|
+
__all__ = ["CorpusEntry", "match_citation", "normalize_citation"]
|
|
16
|
+
|
|
17
|
+
# The minimum length is a guard, not a tuning knob: a fragment this short can
|
|
18
|
+
# appear in a trusted source by coincidence and must not promote an answer.
|
|
19
|
+
MIN_NORMALIZED_LENGTH = 10
|
|
20
|
+
|
|
21
|
+
_WHITESPACE = re.compile(r"\s+")
|
|
22
|
+
_EMPHASIS = re.compile(r"[*_`]")
|
|
23
|
+
_SINGLE_QUOTES = re.compile("[\u2018\u2019]")
|
|
24
|
+
_DOUBLE_QUOTES = re.compile("[\u201c\u201d]")
|
|
25
|
+
_DASHES = re.compile("[\u2013\u2014]")
|
|
26
|
+
|
|
27
|
+
CitationKind = Literal["prose", "definition", "schema"]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass(frozen=True)
|
|
31
|
+
class CorpusEntry:
|
|
32
|
+
"""One trusted passage a citation can be verified against.
|
|
33
|
+
|
|
34
|
+
``label`` is reader-facing and appears in the rendered aside.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
label: str
|
|
38
|
+
kind: CitationKind
|
|
39
|
+
text: str
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def normalize_citation(text: str) -> str:
|
|
43
|
+
"""Fold the ways a faithful quote can still drift from its source.
|
|
44
|
+
|
|
45
|
+
Strips markdown emphasis, folds typographic quotes and dashes to ASCII, and
|
|
46
|
+
collapses runs of whitespace. Case is deliberately preserved, because
|
|
47
|
+
matching is case-sensitive.
|
|
48
|
+
"""
|
|
49
|
+
text = _EMPHASIS.sub("", text)
|
|
50
|
+
text = _SINGLE_QUOTES.sub("'", text)
|
|
51
|
+
text = _DOUBLE_QUOTES.sub('"', text)
|
|
52
|
+
text = _DASHES.sub("-", text)
|
|
53
|
+
return _WHITESPACE.sub(" ", text).strip()
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def match_citation(quote: str, corpus: Sequence[CorpusEntry]) -> CorpusEntry | None:
|
|
57
|
+
"""Find the first corpus entry that contains the quote, or None.
|
|
58
|
+
|
|
59
|
+
Only the quote is ever verified; a model's explanation of it is not passed
|
|
60
|
+
here. Corpus order is meaningful, running specific before general, so the
|
|
61
|
+
first match wins rather than the best one.
|
|
62
|
+
"""
|
|
63
|
+
needle = normalize_citation(quote)
|
|
64
|
+
if len(needle) < MIN_NORMALIZED_LENGTH:
|
|
65
|
+
return None
|
|
66
|
+
return next(
|
|
67
|
+
(entry for entry in corpus if needle in normalize_citation(entry.text)),
|
|
68
|
+
None,
|
|
69
|
+
)
|
commons/_provenance.py
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""A/B/C provenance: how much an answer can be trusted.
|
|
2
|
+
|
|
3
|
+
The truth table and the display copy are a cross-language contract pinned by
|
|
4
|
+
``tests/shared/provenance.json``; change that fixture, not just this file.
|
|
5
|
+
``pkg-r/R/provenance.R`` implements the same contract for R.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import enum
|
|
11
|
+
from collections.abc import Sequence
|
|
12
|
+
from dataclasses import dataclass
|
|
13
|
+
|
|
14
|
+
__all__ = ["PROVENANCE_DISPLAY", "ProvenanceDisplay", "Tag", "derive_provenance_tag"]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Tag(enum.StrEnum):
|
|
18
|
+
"""How an answer was produced.
|
|
19
|
+
|
|
20
|
+
A and B are set by tools on their results. C is only ever derived: it is
|
|
21
|
+
what a B becomes when its citation does not verify.
|
|
22
|
+
|
|
23
|
+
StrEnum rather than a plain `str, Enum` mixin, which formats as "Tag.A".
|
|
24
|
+
The tag is written to the commons.provenance.tag span attribute, where R
|
|
25
|
+
writes the bare letter and a mismatch would corrupt traces silently.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
A = "A"
|
|
29
|
+
B = "B"
|
|
30
|
+
C = "C"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@dataclass(frozen=True)
|
|
34
|
+
class ProvenanceDisplay:
|
|
35
|
+
"""The words and styling one tag's pill renders with."""
|
|
36
|
+
|
|
37
|
+
label: str
|
|
38
|
+
icon: str | None
|
|
39
|
+
body: str
|
|
40
|
+
pill_class: str
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
PROVENANCE_DISPLAY: dict[Tag, ProvenanceDisplay] = {
|
|
44
|
+
Tag.A: ProvenanceDisplay(
|
|
45
|
+
label="Verified answer",
|
|
46
|
+
icon="trusted-icon.svg",
|
|
47
|
+
body=(
|
|
48
|
+
"This answer comes from a governed calculation defined by your data team."
|
|
49
|
+
),
|
|
50
|
+
pill_class="trusted",
|
|
51
|
+
),
|
|
52
|
+
Tag.B: ProvenanceDisplay(
|
|
53
|
+
label="Cited",
|
|
54
|
+
icon=None,
|
|
55
|
+
body="This answer includes supporting text verified against a trusted source.",
|
|
56
|
+
pill_class="cited",
|
|
57
|
+
),
|
|
58
|
+
Tag.C: ProvenanceDisplay(
|
|
59
|
+
label="Untrusted",
|
|
60
|
+
icon="warning-icon.svg",
|
|
61
|
+
body=(
|
|
62
|
+
"This answer was not produced by a governed calculation and has "
|
|
63
|
+
"no verified supporting citation. AI can be wrong."
|
|
64
|
+
),
|
|
65
|
+
pill_class="caution",
|
|
66
|
+
),
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def derive_provenance_tag(tags: Sequence[Tag], verified: bool) -> Tag | None:
|
|
71
|
+
"""Classify one exchange from the tags its tools set.
|
|
72
|
+
|
|
73
|
+
A fallback claim remains fallback even when its answer also uses a governed
|
|
74
|
+
calculation, so its citation verdict takes precedence ("B beats A").
|
|
75
|
+
Returns ``None`` when no data tool ran, which shows no pill at all.
|
|
76
|
+
"""
|
|
77
|
+
if Tag.B in tags:
|
|
78
|
+
return Tag.B if verified else Tag.C
|
|
79
|
+
if Tag.A in tags:
|
|
80
|
+
return Tag.A
|
|
81
|
+
return None
|
commons/py.typed
ADDED
|
File without changes
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: commons
|
|
3
|
+
Version: 0.1.0.dev1
|
|
4
|
+
Summary: AI Agents for Data Analysis
|
|
5
|
+
Project-URL: Homepage, https://github.com/posit-dev/commons
|
|
6
|
+
Project-URL: Issues, https://github.com/posit-dev/commons/issues
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
License-File: LICENSE.md
|
|
9
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
10
|
+
Requires-Python: <3.14,>=3.11
|
|
11
|
+
Requires-Dist: chatlas>=0.21.2
|
|
12
|
+
Requires-Dist: duckdb>=1.0
|
|
13
|
+
Requires-Dist: jinja2>=3
|
|
14
|
+
Requires-Dist: pyarrow>=17
|
|
15
|
+
Requires-Dist: pydantic>=2
|
|
16
|
+
Requires-Dist: pyyaml>=6
|
|
17
|
+
Requires-Dist: raghilda>=0.2
|
|
18
|
+
Requires-Dist: sqlalchemy>=2.0
|
|
19
|
+
Provides-Extra: tracing
|
|
20
|
+
Requires-Dist: httpx>=0.27; extra == 'tracing'
|
|
21
|
+
Requires-Dist: opentelemetry-exporter-otlp-json-file; extra == 'tracing'
|
|
22
|
+
Requires-Dist: opentelemetry-sdk>=1.39; extra == 'tracing'
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# commons
|
|
26
|
+
|
|
27
|
+
`commons` is a constructor for trustworthy data agents. Once implemented, this package will give an LLM data, semantic, and context layers to work with, tools for querying them, and A/B/C provenance tags so every answer carries a classification as to its trustworthiness.
|
|
28
|
+
|
|
29
|
+
**Status: pre-alpha.** The package installs, imports, lints, type-checks, and tests, but exports nothing yet: `commons.__all__` is empty and there is no public API. Python 3.11 or later is required.
|
|
30
|
+
|
|
31
|
+
Behavior that both implementations must agree on belongs in [`tests/shared/`](https://github.com/posit-dev/commons/tree/main/tests/shared) at the repository root, which that directory's README defines as the authority. The provenance tag rules and display copy are the first behavior governed that way; both suites run those cases.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
commons/__init__.py,sha256=ClGErzI1C7jkP4Dyr0N0u4QM6yyrfljPy6L3P-0MHHI,256
|
|
2
|
+
commons/_citations.py,sha256=oSzcXVxGo4SMLfuARKJs0Q4LMt4-fhdk82Ec62IsdK0,2268
|
|
3
|
+
commons/_provenance.py,sha256=5HqR1Ky8ILP59ltIMC0YYT0bjQTSiqyV_gIpokGEXxU,2423
|
|
4
|
+
commons/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
commons-0.1.0.dev1.dist-info/METADATA,sha256=CW3l-RdvIQ0B9ukRT6k-rUhB5rEloyOW76IbUO46xAQ,1627
|
|
6
|
+
commons-0.1.0.dev1.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
|
|
7
|
+
commons-0.1.0.dev1.dist-info/licenses/LICENSE.md,sha256=cXVvzpR07jRZuWPH_VAvnN2LOaOEJxI4yrbU0Nl_1fM,1078
|
|
8
|
+
commons-0.1.0.dev1.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Posit Software, PBC
|
|
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.
|