Skip to content

Commit 305987c

Browse files
committed
Extract standalone TRACE Python SDK
Create the dedicated latence-trace-python SDK repo that publishes the existing latence package with a thin TRACE-first client, session storage, contract checks, and PyPI trusted publishing setup.
0 parents  commit 305987c

41 files changed

Lines changed: 4171 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/publish.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: Publish
2+
3+
on:
4+
release:
5+
types: [published]
6+
7+
permissions:
8+
contents: read
9+
id-token: write
10+
11+
jobs:
12+
publish:
13+
name: Publish to PyPI
14+
runs-on: ubuntu-latest
15+
environment: pypi
16+
steps:
17+
- uses: actions/checkout@v4
18+
19+
- uses: actions/setup-python@v5
20+
with:
21+
python-version: "3.12"
22+
23+
- name: Install build tooling
24+
run: python -m pip install --upgrade build twine
25+
26+
- name: Build
27+
run: python -m build
28+
29+
- name: Check distributions
30+
run: python -m twine check dist/*
31+
32+
- name: Publish
33+
uses: pypa/gh-action-pypi-publish@release/v1

.github/workflows/test.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: Test
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches: [main]
7+
8+
permissions:
9+
contents: read
10+
11+
jobs:
12+
test:
13+
runs-on: ubuntu-latest
14+
strategy:
15+
fail-fast: false
16+
matrix:
17+
python-version: ["3.10", "3.11", "3.12"]
18+
steps:
19+
- uses: actions/checkout@v4
20+
21+
- uses: actions/setup-python@v5
22+
with:
23+
python-version: ${{ matrix.python-version }}
24+
25+
- name: Install
26+
run: python -m pip install -e ".[dev]"
27+
28+
- name: Lint
29+
run: python -m ruff check .
30+
31+
- name: Test
32+
run: python -m pytest

.gitignore

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
__pycache__/
2+
*.py[cod]
3+
.pytest_cache/
4+
.ruff_cache/
5+
.mypy_cache/
6+
.venv/
7+
dist/
8+
build/
9+
*.egg-info/
10+
.trace-sessions/
11+
.env
12+
.env.*
13+
!.env.example

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 latence.ai
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.

README.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Latence Python SDK
2+
3+
Thin Python SDK for Latence TRACE.
4+
5+
```bash
6+
pip install latence
7+
```
8+
9+
```python
10+
from latence import Latence
11+
12+
client = Latence(api_key="lat_...")
13+
14+
result = client.grounding.rag(
15+
query="When will this customer be refunded?",
16+
response_text="The customer will be refunded within 48 hours.",
17+
raw_context="Refunds are reviewed manually after finance approval.",
18+
)
19+
20+
print(result.risk_band)
21+
```
22+
23+
## Surface
24+
25+
The SDK maps 1:1 to the TRACE product API:
26+
27+
- `client.privacy.redact(...)`
28+
- `client.grounding.rag(...)`
29+
- `client.grounding.code(...)`
30+
- `client.compression.text(...)`
31+
- `client.compression.messages(...)`
32+
- `client.memory.step(...)`
33+
- `client.rollup(...)`
34+
- `client.session(...)`
35+
36+
`Latence` is the sync client. `AsyncLatence` exposes the same product namespaces for asyncio apps.
37+
38+
## Sessions
39+
40+
TRACE deployments are stateless by default. The SDK owns caller-carried session state for agent workflows that need memory continuity, rollups, idempotency, and local persistence.
41+
42+
```python
43+
from latence import FileSessionStorage, Latence
44+
45+
client = Latence(api_key="lat_...")
46+
session = client.session(
47+
session_id="support-run-42",
48+
storage=FileSessionStorage(".trace-sessions"),
49+
)
50+
51+
session.event("tool", "loaded refund policy")
52+
session.memory_step(turn_text="Keep finance approval as required context.")
53+
score = session.rag(
54+
query="Can I promise the refund?",
55+
response_text="Yes, the refund is guaranteed in 48 hours.",
56+
raw_context="Refunds require manual finance approval.",
57+
)
58+
session.save()
59+
```
60+
61+
## Compatibility
62+
63+
The primary import is:
64+
65+
```python
66+
from latence import Latence, AsyncLatence
67+
```
68+
69+
For migration from the TRACE preview SDK, `LatenceTraceClient` and `AsyncLatenceTraceClient` remain aliases.
70+
71+
## Development
72+
73+
```bash
74+
python -m pip install -e ".[dev]"
75+
python -m pytest
76+
python -m ruff check .
77+
python -m build
78+
python -m twine check dist/*
79+
```
80+
81+
Set `LATENCE_TRACE_RUNTIME_REPO=/path/to/latence-trace` when running contract tests from a non-sibling checkout.

docs/errors.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Errors
2+
3+
All SDK exceptions inherit from `LatenceTraceAPIError`.
4+
5+
Common subclasses:
6+
7+
- `LatenceTraceAuthError` for invalid or missing credentials.
8+
- `LatenceTraceRateLimited` for HTTP 429 responses. The `retry_after` attribute is set when the server provides it.
9+
- `LatenceTraceTimeout` for client-side timeouts.
10+
- `LatenceTraceValidationError` for request validation errors.
11+
- `LatenceTraceServerError` for malformed or failed server responses.
12+
13+
The SDK retries transient `408`, `409`, `425`, `429`, and `5xx` responses according to `RetryPolicy`.

docs/integrations.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Integrations
2+
3+
The core SDK has only `httpx` and `pydantic` runtime dependencies.
4+
5+
Optional integration helpers live under `latence.integrations` and are activated through extras:
6+
7+
```bash
8+
pip install "latence[langchain]"
9+
pip install "latence[llama_index]"
10+
pip install "latence[openai]"
11+
```
12+
13+
The recommended baseline for frameworks such as LangChain, LangGraph, LlamaIndex, n8n, Cursor, Claude Code, and Codex is to call the explicit product methods directly:
14+
15+
```python
16+
from latence import Latence
17+
18+
trace = Latence()
19+
decision = trace.grounding.rag(
20+
query=user_question,
21+
response_text=agent_answer,
22+
raw_context=retrieved_context,
23+
)
24+
```
25+
26+
This keeps the integration thin and makes TRACE decisions easy to log, replay, and route.

docs/publishing.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# PyPI Publishing
2+
3+
PyPI project: `latence`
4+
5+
Trusted Publisher settings:
6+
7+
- Publisher: GitHub
8+
- Owner: `latenceainew`
9+
- Repository: `latence-trace-python`
10+
- Workflow filename: `publish.yml`
11+
- Environment name: `pypi`
12+
13+
No PyPI API token is required when Trusted Publishing is enabled.
14+
15+
Release flow:
16+
17+
1. Confirm the version in `pyproject.toml` has not been uploaded before.
18+
2. Run `python -m pytest`, `python -m ruff check .`, `python -m build`, and `python -m twine check dist/*`.
19+
3. Create and push a release tag, for example `v1.0.0`.
20+
4. Publish through the protected `pypi` GitHub environment.

docs/quickstart.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Quickstart
2+
3+
Install:
4+
5+
```bash
6+
pip install latence
7+
```
8+
9+
Score a RAG response:
10+
11+
```python
12+
from latence import Latence
13+
14+
client = Latence(api_key="lat_...")
15+
score = client.grounding.rag(
16+
query="Can this invoice be refunded?",
17+
response_text="Yes, it will be refunded within 48 hours.",
18+
raw_context="Refunds require manual finance approval.",
19+
)
20+
print(score.risk_band)
21+
```
22+
23+
Use `AsyncLatence` for asyncio services. The async surface mirrors the sync client.

docs/sessions.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Sessions
2+
3+
TRACE compute deployments are stateless. The Python SDK carries optional session state on the caller side so agent runs can preserve memory state, idempotency keys, events, and rollup inputs without requiring shared server storage.
4+
5+
```python
6+
from latence import FileSessionStorage, Latence
7+
8+
client = Latence()
9+
session = client.session(
10+
session_id="agent-run-1",
11+
storage=FileSessionStorage(".trace-sessions"),
12+
)
13+
14+
session.event("tool", "loaded customer policy")
15+
session.memory_step(turn_text="Keep the manual approval rule active.")
16+
score = session.rag(
17+
query="Can we promise a refund?",
18+
response_text="The refund is guaranteed.",
19+
raw_context="Refunds require finance approval.",
20+
)
21+
session.save()
22+
```
23+
24+
Use `InMemorySessionStorage` for tests and short-lived processes. Use `FileSessionStorage` for local agents and CLI workflows.

0 commit comments

Comments
 (0)