trooth 0.2.0__tar.gz → 0.3.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.
- {trooth-0.2.0 → trooth-0.3.0}/PKG-INFO +4 -1
- {trooth-0.2.0 → trooth-0.3.0}/README.md +3 -0
- {trooth-0.2.0 → trooth-0.3.0}/pyproject.toml +1 -1
- {trooth-0.2.0 → trooth-0.3.0}/trooth/__init__.py +1 -1
- {trooth-0.2.0 → trooth-0.3.0}/trooth.egg-info/PKG-INFO +4 -1
- {trooth-0.2.0 → trooth-0.3.0}/trooth_semanto_verify/__init__.py +1 -1
- {trooth-0.2.0 → trooth-0.3.0}/trooth_semanto_verify/answer.py +17 -0
- {trooth-0.2.0 → trooth-0.3.0}/trooth_semanto_verify/source.py +5 -1
- {trooth-0.2.0 → trooth-0.3.0}/LICENSE +0 -0
- {trooth-0.2.0 → trooth-0.3.0}/setup.cfg +0 -0
- {trooth-0.2.0 → trooth-0.3.0}/trooth/integrations/__init__.py +0 -0
- {trooth-0.2.0 → trooth-0.3.0}/trooth/integrations/langchain.py +0 -0
- {trooth-0.2.0 → trooth-0.3.0}/trooth/integrations/llama_index.py +0 -0
- {trooth-0.2.0 → trooth-0.3.0}/trooth/integrations/openai_agents.py +0 -0
- {trooth-0.2.0 → trooth-0.3.0}/trooth.egg-info/SOURCES.txt +0 -0
- {trooth-0.2.0 → trooth-0.3.0}/trooth.egg-info/dependency_links.txt +0 -0
- {trooth-0.2.0 → trooth-0.3.0}/trooth.egg-info/entry_points.txt +0 -0
- {trooth-0.2.0 → trooth-0.3.0}/trooth.egg-info/requires.txt +0 -0
- {trooth-0.2.0 → trooth-0.3.0}/trooth.egg-info/top_level.txt +0 -0
- {trooth-0.2.0 → trooth-0.3.0}/trooth_semanto_verify/__main__.py +0 -0
- {trooth-0.2.0 → trooth-0.3.0}/trooth_semanto_verify/canonical.py +0 -0
- {trooth-0.2.0 → trooth-0.3.0}/trooth_semanto_verify/cli.py +0 -0
- {trooth-0.2.0 → trooth-0.3.0}/trooth_semanto_verify/client.py +0 -0
- {trooth-0.2.0 → trooth-0.3.0}/trooth_semanto_verify/httpsig.py +0 -0
- {trooth-0.2.0 → trooth-0.3.0}/trooth_semanto_verify/jws.py +0 -0
- {trooth-0.2.0 → trooth-0.3.0}/trooth_semanto_verify/merkle.py +0 -0
- {trooth-0.2.0 → trooth-0.3.0}/trooth_semanto_verify/verify.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: trooth
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Read a company's Semanto signed copy and check it: signatures, keys, DNS binding, page proofs and the public log.
|
|
5
5
|
Author: Trooth, LLC
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -94,6 +94,9 @@ from trooth import SemantoSource
|
|
|
94
94
|
acme = SemantoSource("acme.com", on_event=lambda e: print(e["event"], e["detail"]))
|
|
95
95
|
a = acme.answer(question="How much is the Starter plan?")
|
|
96
96
|
print(a["status"], a["text"])
|
|
97
|
+
|
|
98
|
+
r = acme.reply(question=user_question, draft=model_text) # built by code; the draft is discarded
|
|
99
|
+
show(r["text"])
|
|
97
100
|
```
|
|
98
101
|
|
|
99
102
|
It loads `/.well-known/trooth.semanto` and the company's keys from the company's site, checks the file once for each new body, reads the site again at most every 15 minutes, and answers fact IDs and plain questions in process with the same matcher as Trooth's service (`trooth_semanto_verify.answer`, compared case by case with `verifier/test-vectors/answer-v1`). When Trooth's API cannot be reached it keeps answering from the last version that checked out and logs `trooth_api_unreachable`; a new version that does not check out is refused and the last good one stays in use. A fact marked changed since signing or expired returns its mark and no value.
|
|
@@ -64,6 +64,9 @@ from trooth import SemantoSource
|
|
|
64
64
|
acme = SemantoSource("acme.com", on_event=lambda e: print(e["event"], e["detail"]))
|
|
65
65
|
a = acme.answer(question="How much is the Starter plan?")
|
|
66
66
|
print(a["status"], a["text"])
|
|
67
|
+
|
|
68
|
+
r = acme.reply(question=user_question, draft=model_text) # built by code; the draft is discarded
|
|
69
|
+
show(r["text"])
|
|
67
70
|
```
|
|
68
71
|
|
|
69
72
|
It loads `/.well-known/trooth.semanto` and the company's keys from the company's site, checks the file once for each new body, reads the site again at most every 15 minutes, and answers fact IDs and plain questions in process with the same matcher as Trooth's service (`trooth_semanto_verify.answer`, compared case by case with `verifier/test-vectors/answer-v1`). When Trooth's API cannot be reached it keeps answering from the last version that checked out and logs `trooth_api_unreachable`; a new version that does not check out is refused and the last good one stays in use. A fact marked changed since signing or expired returns its mark and no value.
|
|
@@ -12,7 +12,7 @@ build-backend = "setuptools.build_meta"
|
|
|
12
12
|
|
|
13
13
|
[project]
|
|
14
14
|
name = "trooth"
|
|
15
|
-
version = "0.
|
|
15
|
+
version = "0.3.0"
|
|
16
16
|
description = "Read a company's Semanto signed copy and check it: signatures, keys, DNS binding, page proofs and the public log."
|
|
17
17
|
readme = "README.md"
|
|
18
18
|
requires-python = ">=3.11"
|
|
@@ -14,5 +14,5 @@ kits). Framework integrations are optional extras: trooth[langchain], trooth[lla
|
|
|
14
14
|
from trooth_semanto_verify.client import SemantoClient
|
|
15
15
|
from trooth_semanto_verify.source import SemantoSource
|
|
16
16
|
|
|
17
|
-
__version__ = "0.
|
|
17
|
+
__version__ = "0.3.0"
|
|
18
18
|
__all__ = ["SemantoClient", "SemantoSource", "__version__"]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: trooth
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Read a company's Semanto signed copy and check it: signatures, keys, DNS binding, page proofs and the public log.
|
|
5
5
|
Author: Trooth, LLC
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -94,6 +94,9 @@ from trooth import SemantoSource
|
|
|
94
94
|
acme = SemantoSource("acme.com", on_event=lambda e: print(e["event"], e["detail"]))
|
|
95
95
|
a = acme.answer(question="How much is the Starter plan?")
|
|
96
96
|
print(a["status"], a["text"])
|
|
97
|
+
|
|
98
|
+
r = acme.reply(question=user_question, draft=model_text) # built by code; the draft is discarded
|
|
99
|
+
show(r["text"])
|
|
97
100
|
```
|
|
98
101
|
|
|
99
102
|
It loads `/.well-known/trooth.semanto` and the company's keys from the company's site, checks the file once for each new body, reads the site again at most every 15 minutes, and answers fact IDs and plain questions in process with the same matcher as Trooth's service (`trooth_semanto_verify.answer`, compared case by case with `verifier/test-vectors/answer-v1`). When Trooth's API cannot be reached it keeps answering from the last version that checked out and logs `trooth_api_unreachable`; a new version that does not check out is refused and the last good one stays in use. A fact marked changed since signing or expired returns its mark and no value.
|
|
@@ -170,3 +170,20 @@ def answer(file: dict, company: dict, fact_id: Optional[str] = None, question: O
|
|
|
170
170
|
lines = [MARK_WORDS[mark]] if mark else [f["statement"], *([f"Conditions: {'; '.join(f['conditions'])}."] if f.get("conditions") else [])]
|
|
171
171
|
lines.append(f"Check: {check}")
|
|
172
172
|
return {**base, "status": "answer", "matched_by": by, "facts": [_as_answered(f, mark)], "text": "\n".join(lines[:3])}
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def assemble_reply(a: dict, draft: Optional[str] = None) -> dict:
|
|
176
|
+
"""What the customer is shown, built by code from an answer; a model's own wording is never part of it.
|
|
177
|
+
|
|
178
|
+
For a value answer the first line is the signed sentence exactly as signed, then its conditions if any, then the day
|
|
179
|
+
it was signed and the check link. A marked fact shows its mark instead of a value. Candidates, the not-published
|
|
180
|
+
reply and not_read show the answer's own fixed line. `draft` (what a model wrote) is accepted and discarded:
|
|
181
|
+
`discarded` says whether one was given."""
|
|
182
|
+
discarded = isinstance(draft, str) and len(draft) > 0
|
|
183
|
+
signed_on = str(a["signed_at"])[:10] if a.get("signed_at") else None
|
|
184
|
+
f = a["facts"][0] if a["status"] == "answer" else None
|
|
185
|
+
if not f:
|
|
186
|
+
return {"status": a["status"], "fact_id": None, "statement": None, "signed_on": signed_on, "check": a.get("check"), "text": a["text"], "discarded": discarded}
|
|
187
|
+
tail = f"{f'Signed on {signed_on}. ' if signed_on else ''}Check: {a['check']}"
|
|
188
|
+
lines = [MARK_WORDS[f["mark"]], tail] if f["mark"] else [f["statement"], *([f"Conditions: {'; '.join(f['conditions'])}."] if f["conditions"] else []), tail]
|
|
189
|
+
return {"status": a["status"], "fact_id": f["fact_id"], "statement": f["statement"], "signed_on": signed_on, "check": a["check"], "text": "\n".join(lines), "discarded": discarded}
|
|
@@ -28,7 +28,7 @@ from datetime import datetime, timezone
|
|
|
28
28
|
from typing import Any, Callable, Dict, List, Optional
|
|
29
29
|
|
|
30
30
|
from .answer import answer as _answer
|
|
31
|
-
from .answer import fact_marks
|
|
31
|
+
from .answer import assemble_reply, fact_marks
|
|
32
32
|
from .client import Fetch, urllib_fetch
|
|
33
33
|
from .verify import verify_semanto
|
|
34
34
|
|
|
@@ -152,3 +152,7 @@ class SemantoSource:
|
|
|
152
152
|
return {"object": "semanto.answer", "status": "not_read", "matched_by": None, "company": {"trooth_id": None, "name": None, "domain": self.domain},
|
|
153
153
|
"version": None, "facts": [], "text": f"No signed record of {self.domain} could be read and checked yet."}
|
|
154
154
|
return _answer(self.file, self.company, fact_id=fact_id, question=question, marks=self.marks(), check_base=f"{self.api_base}/public/semanto")
|
|
155
|
+
|
|
156
|
+
def reply(self, fact_id: Optional[str] = None, question: Optional[str] = None, draft: Optional[str] = None) -> dict:
|
|
157
|
+
"""The reply a chatbot shows for a question: built by code from the signed record, with the model's draft discarded."""
|
|
158
|
+
return assemble_reply(self.answer(fact_id=fact_id, question=question), draft)
|
|
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
|