tessera-llm-proxy 0.1.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.
@@ -0,0 +1,6 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .pytest_cache/
4
+ *.egg-info/
5
+ dist/
6
+ build/
@@ -0,0 +1,153 @@
1
+ Metadata-Version: 2.4
2
+ Name: tessera-llm-proxy
3
+ Version: 0.1.0
4
+ Summary: Tessera SDK — drop-in LLM cost optimization. One line patches OpenAI, Anthropic, Mistral, Groq, Cohere clients to route through Tessera's auto-route + auto-cache + auto-compress + auto-batch proxy. Free tier: 60M tokens/mo. Production: 20% of measured savings, $0 if none.
5
+ Project-URL: Homepage, https://tesseraai.io
6
+ Project-URL: Documentation, https://tesseraai.io/dev
7
+ Project-URL: Repository, https://github.com/tessera-llm/sdk
8
+ Project-URL: Issues, https://github.com/tessera-llm/sdk/issues
9
+ Project-URL: Changelog, https://github.com/tessera-llm/sdk/releases
10
+ Author-email: "Tessera (Fintechagency OÜ)" <contact@tesseraai.io>
11
+ License: Apache-2.0
12
+ Keywords: ai-cost,ai-proxy,anthropic,claude,cohere,cost-optimization,gemini,gpt-4o,groq,llm,llm-cost,llm-proxy,mistral,observability,openai,tessera
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: Apache Software License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3 :: Only
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
24
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
25
+ Requires-Python: >=3.9
26
+ Provides-Extra: test
27
+ Requires-Dist: pytest-mock>=3.0; extra == 'test'
28
+ Requires-Dist: pytest>=7.0; extra == 'test'
29
+ Description-Content-Type: text/markdown
30
+
31
+ # tessera-llm-proxy
32
+
33
+ [![PyPI version](https://img.shields.io/pypi/v/tessera-llm-proxy.svg)](https://pypi.org/project/tessera-llm-proxy/)
34
+ [![Python](https://img.shields.io/pypi/pyversions/tessera-llm-proxy.svg)](https://pypi.org/project/tessera-llm-proxy/)
35
+
36
+ **Drop-in cost optimization for LLM applications.** One line of code patches your existing OpenAI / Anthropic / Mistral / DeepSeek / Groq / Together / Fireworks / OpenRouter / Perplexity / Cerebras / xAI client to route through Tessera's measurement + auto-optimize proxy. You keep your provider account and keys; we route + cache + compress and measure savings on every request.
37
+
38
+ > Free Dev tier: **60M tokens / month · no card required · no fee until you upgrade.** Get your free key at [tesseraai.io/dev](https://tesseraai.io/dev).
39
+
40
+ ## Get a free API key
41
+
42
+ → **[Get free key](https://ledger.tesseraai.io/signup-dev)** (email + ToS, 30 seconds, no card)
43
+
44
+ After signup you get:
45
+ - Your `tk_` API key (shown once)
46
+ - A magic-link for the [dashboard](https://ledger.tesseraai.io/portal) — see your token counter + savings counter live
47
+ - 60M tokens/month at 10 req/min — generous for hobby + side projects
48
+
49
+ ## Install
50
+
51
+ ```bash
52
+ pip install tessera-llm-proxy
53
+ ```
54
+
55
+ ## One-line setup
56
+
57
+ Drop this at the top of your application's entry point (`main.py`, `app.py`, `manage.py`, wherever your app boots):
58
+
59
+ ```python
60
+ import tessera
61
+ tessera.activate("tk_your_tessera_key")
62
+ ```
63
+
64
+ That's it. Your existing code runs unchanged — `openai.OpenAI()`, `anthropic.Anthropic()`, `mistralai.Mistral()`, and other supported SDK constructors are transparently patched to route through Tessera. Your provider keys (OpenAI `sk-...`, Anthropic `sk-ant-...`, etc.) stay in your environment as before; Tessera forwards them upstream untouched.
65
+
66
+ ### Environment variable form
67
+
68
+ If you'd rather not put the key in code:
69
+
70
+ ```bash
71
+ export TESSERA_KEY=tk_your_tessera_key
72
+ ```
73
+
74
+ ```python
75
+ import tessera
76
+ tessera.activate() # reads TESSERA_KEY from environment
77
+ ```
78
+
79
+ ## What gets patched
80
+
81
+ Calling `tessera.activate(...)` patches the following SDKs at import time (each is opt-in: only patched if the library is installed):
82
+
83
+ | SDK | Tessera route |
84
+ | --- | --- |
85
+ | `openai` (≥1.0) | `https://api.tesseraai.io/v1/openai` |
86
+ | `anthropic` | `https://api.tesseraai.io/v1/anthropic` |
87
+ | `mistralai` | `https://api.tesseraai.io/v1/mistral` |
88
+ | `cohere` | `https://api.tesseraai.io/v1/cohere` *(Wave 2)* |
89
+ | `groq` | `https://api.tesseraai.io/v1/groq` |
90
+
91
+ If you use a framework that wraps these SDKs (LangChain, LlamaIndex, CrewAI, AutoGen, Mastra, Pydantic AI, etc.), the patch applies transparently because those frameworks call the underlying SDK constructors which are what we patched.
92
+
93
+ ## Direct provider URLs
94
+
95
+ If you call providers that aren't covered by an official Python SDK (DeepSeek, Together, Fireworks, OpenRouter, Perplexity, Cerebras, xAI), construct an `openai.OpenAI` client manually with the matching Tessera URL:
96
+
97
+ ```python
98
+ from openai import OpenAI
99
+
100
+ # DeepSeek via Tessera
101
+ client = OpenAI(
102
+ api_key="sk-deepseek-...",
103
+ base_url=tessera.url("deepseek"), # → https://api.tesseraai.io/v1/deepseek
104
+ default_headers=tessera.headers(),
105
+ )
106
+
107
+ # Same pattern for: together, fireworks, openrouter, perplexity, cerebras, groq, xai
108
+ ```
109
+
110
+ `tessera.url(provider)` and `tessera.headers()` are pure helpers — no globals, no patching. Use them when you want explicit, traceable wiring.
111
+
112
+ ## Verification
113
+
114
+ ```python
115
+ import tessera
116
+ tessera.activate("tk_...")
117
+
118
+ assert tessera.is_active(), "Tessera should be active after activate()"
119
+ print(tessera.status()) # → ProxyStatus(active=True, providers_patched=['openai', 'anthropic'], proxy_base='https://api.tesseraai.io/v1')
120
+ ```
121
+
122
+ ## Deactivation
123
+
124
+ To restore the original SDK constructors (e.g. in test teardown):
125
+
126
+ ```python
127
+ tessera.deactivate()
128
+ ```
129
+
130
+ ## Configuration
131
+
132
+ ```python
133
+ tessera.activate(
134
+ key="tk_...", # or TESSERA_KEY env var
135
+ proxy_base="https://api.tesseraai.io/v1", # default; override for staging/dev
136
+ feature_tag="checkout-summarizer", # attaches to every request for per-feature attribution
137
+ )
138
+ ```
139
+
140
+ `feature_tag` lets you split savings reporting per workload (e.g. one tag per logical feature in your app). You can also set per-request tags by passing `extra_body={"tessera_feature_tag": "..."}` on individual SDK calls.
141
+
142
+ ## How the pricing works
143
+
144
+ - **Free Sandbox tier:** 60M tokens/month, no card required, $0 fee.
145
+ - **Production tier:** **20%** of measured savings, debited daily from a prepaid balance you control ($100 minimum top-up via Stripe).
146
+ - **Zero savings = zero fee.** If our optimization doesn't save you anything in a period, you pay nothing for that period.
147
+ - **Kill-switch** available anytime from your portal — pauses optimization, traffic still flows passthrough.
148
+
149
+ Full terms: <https://tesseraai.io/terms>
150
+
151
+ ## License
152
+
153
+ Apache-2.0
@@ -0,0 +1,123 @@
1
+ # tessera-llm-proxy
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/tessera-llm-proxy.svg)](https://pypi.org/project/tessera-llm-proxy/)
4
+ [![Python](https://img.shields.io/pypi/pyversions/tessera-llm-proxy.svg)](https://pypi.org/project/tessera-llm-proxy/)
5
+
6
+ **Drop-in cost optimization for LLM applications.** One line of code patches your existing OpenAI / Anthropic / Mistral / DeepSeek / Groq / Together / Fireworks / OpenRouter / Perplexity / Cerebras / xAI client to route through Tessera's measurement + auto-optimize proxy. You keep your provider account and keys; we route + cache + compress and measure savings on every request.
7
+
8
+ > Free Dev tier: **60M tokens / month · no card required · no fee until you upgrade.** Get your free key at [tesseraai.io/dev](https://tesseraai.io/dev).
9
+
10
+ ## Get a free API key
11
+
12
+ → **[Get free key](https://ledger.tesseraai.io/signup-dev)** (email + ToS, 30 seconds, no card)
13
+
14
+ After signup you get:
15
+ - Your `tk_` API key (shown once)
16
+ - A magic-link for the [dashboard](https://ledger.tesseraai.io/portal) — see your token counter + savings counter live
17
+ - 60M tokens/month at 10 req/min — generous for hobby + side projects
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ pip install tessera-llm-proxy
23
+ ```
24
+
25
+ ## One-line setup
26
+
27
+ Drop this at the top of your application's entry point (`main.py`, `app.py`, `manage.py`, wherever your app boots):
28
+
29
+ ```python
30
+ import tessera
31
+ tessera.activate("tk_your_tessera_key")
32
+ ```
33
+
34
+ That's it. Your existing code runs unchanged — `openai.OpenAI()`, `anthropic.Anthropic()`, `mistralai.Mistral()`, and other supported SDK constructors are transparently patched to route through Tessera. Your provider keys (OpenAI `sk-...`, Anthropic `sk-ant-...`, etc.) stay in your environment as before; Tessera forwards them upstream untouched.
35
+
36
+ ### Environment variable form
37
+
38
+ If you'd rather not put the key in code:
39
+
40
+ ```bash
41
+ export TESSERA_KEY=tk_your_tessera_key
42
+ ```
43
+
44
+ ```python
45
+ import tessera
46
+ tessera.activate() # reads TESSERA_KEY from environment
47
+ ```
48
+
49
+ ## What gets patched
50
+
51
+ Calling `tessera.activate(...)` patches the following SDKs at import time (each is opt-in: only patched if the library is installed):
52
+
53
+ | SDK | Tessera route |
54
+ | --- | --- |
55
+ | `openai` (≥1.0) | `https://api.tesseraai.io/v1/openai` |
56
+ | `anthropic` | `https://api.tesseraai.io/v1/anthropic` |
57
+ | `mistralai` | `https://api.tesseraai.io/v1/mistral` |
58
+ | `cohere` | `https://api.tesseraai.io/v1/cohere` *(Wave 2)* |
59
+ | `groq` | `https://api.tesseraai.io/v1/groq` |
60
+
61
+ If you use a framework that wraps these SDKs (LangChain, LlamaIndex, CrewAI, AutoGen, Mastra, Pydantic AI, etc.), the patch applies transparently because those frameworks call the underlying SDK constructors which are what we patched.
62
+
63
+ ## Direct provider URLs
64
+
65
+ If you call providers that aren't covered by an official Python SDK (DeepSeek, Together, Fireworks, OpenRouter, Perplexity, Cerebras, xAI), construct an `openai.OpenAI` client manually with the matching Tessera URL:
66
+
67
+ ```python
68
+ from openai import OpenAI
69
+
70
+ # DeepSeek via Tessera
71
+ client = OpenAI(
72
+ api_key="sk-deepseek-...",
73
+ base_url=tessera.url("deepseek"), # → https://api.tesseraai.io/v1/deepseek
74
+ default_headers=tessera.headers(),
75
+ )
76
+
77
+ # Same pattern for: together, fireworks, openrouter, perplexity, cerebras, groq, xai
78
+ ```
79
+
80
+ `tessera.url(provider)` and `tessera.headers()` are pure helpers — no globals, no patching. Use them when you want explicit, traceable wiring.
81
+
82
+ ## Verification
83
+
84
+ ```python
85
+ import tessera
86
+ tessera.activate("tk_...")
87
+
88
+ assert tessera.is_active(), "Tessera should be active after activate()"
89
+ print(tessera.status()) # → ProxyStatus(active=True, providers_patched=['openai', 'anthropic'], proxy_base='https://api.tesseraai.io/v1')
90
+ ```
91
+
92
+ ## Deactivation
93
+
94
+ To restore the original SDK constructors (e.g. in test teardown):
95
+
96
+ ```python
97
+ tessera.deactivate()
98
+ ```
99
+
100
+ ## Configuration
101
+
102
+ ```python
103
+ tessera.activate(
104
+ key="tk_...", # or TESSERA_KEY env var
105
+ proxy_base="https://api.tesseraai.io/v1", # default; override for staging/dev
106
+ feature_tag="checkout-summarizer", # attaches to every request for per-feature attribution
107
+ )
108
+ ```
109
+
110
+ `feature_tag` lets you split savings reporting per workload (e.g. one tag per logical feature in your app). You can also set per-request tags by passing `extra_body={"tessera_feature_tag": "..."}` on individual SDK calls.
111
+
112
+ ## How the pricing works
113
+
114
+ - **Free Sandbox tier:** 60M tokens/month, no card required, $0 fee.
115
+ - **Production tier:** **20%** of measured savings, debited daily from a prepaid balance you control ($100 minimum top-up via Stripe).
116
+ - **Zero savings = zero fee.** If our optimization doesn't save you anything in a period, you pay nothing for that period.
117
+ - **Kill-switch** available anytime from your portal — pauses optimization, traffic still flows passthrough.
118
+
119
+ Full terms: <https://tesseraai.io/terms>
120
+
121
+ ## License
122
+
123
+ Apache-2.0
@@ -0,0 +1,63 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "tessera-llm-proxy"
7
+ version = "0.1.0"
8
+ description = "Tessera SDK — drop-in LLM cost optimization. One line patches OpenAI, Anthropic, Mistral, Groq, Cohere clients to route through Tessera's auto-route + auto-cache + auto-compress + auto-batch proxy. Free tier: 60M tokens/mo. Production: 20% of measured savings, $0 if none."
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = { text = "Apache-2.0" }
12
+ authors = [
13
+ { name = "Tessera (Fintechagency OÜ)", email = "contact@tesseraai.io" }
14
+ ]
15
+ keywords = [
16
+ "tessera",
17
+ "llm",
18
+ "openai",
19
+ "anthropic",
20
+ "mistral",
21
+ "groq",
22
+ "cohere",
23
+ "cost-optimization",
24
+ "ai-cost",
25
+ "llm-cost",
26
+ "ai-proxy",
27
+ "llm-proxy",
28
+ "observability",
29
+ "gpt-4o",
30
+ "claude",
31
+ "gemini",
32
+ ]
33
+ classifiers = [
34
+ "Development Status :: 4 - Beta",
35
+ "Intended Audience :: Developers",
36
+ "License :: OSI Approved :: Apache Software License",
37
+ "Operating System :: OS Independent",
38
+ "Programming Language :: Python :: 3",
39
+ "Programming Language :: Python :: 3 :: Only",
40
+ "Programming Language :: Python :: 3.9",
41
+ "Programming Language :: Python :: 3.10",
42
+ "Programming Language :: Python :: 3.11",
43
+ "Programming Language :: Python :: 3.12",
44
+ "Topic :: Software Development :: Libraries :: Python Modules",
45
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
46
+ ]
47
+ dependencies = []
48
+
49
+ [project.optional-dependencies]
50
+ test = [
51
+ "pytest>=7.0",
52
+ "pytest-mock>=3.0",
53
+ ]
54
+
55
+ [project.urls]
56
+ Homepage = "https://tesseraai.io"
57
+ Documentation = "https://tesseraai.io/dev"
58
+ Repository = "https://github.com/tessera-llm/sdk"
59
+ Issues = "https://github.com/tessera-llm/sdk/issues"
60
+ Changelog = "https://github.com/tessera-llm/sdk/releases"
61
+
62
+ [tool.hatch.build.targets.wheel]
63
+ packages = ["tessera"]
@@ -0,0 +1,47 @@
1
+ """Tessera Optimize Layer — drop-in cost optimization for LLM SDKs.
2
+
3
+ One line of code patches OpenAI / Anthropic / Mistral / Groq / Cohere client
4
+ constructors so requests route through Tessera's measurement + auto-optimize
5
+ proxy. Your existing application code runs unchanged.
6
+
7
+ Typical use::
8
+
9
+ import tessera
10
+ tessera.activate("tk_your_tessera_key")
11
+
12
+ # Now any existing OpenAI/Anthropic/etc client created in this Python
13
+ # process will transparently forward through Tessera. No further code
14
+ # changes required.
15
+
16
+ For SDKs we don't auto-patch (DeepSeek/Together/Fireworks/OpenRouter/etc),
17
+ use ``tessera.url(provider)`` + ``tessera.headers()`` to wire an
18
+ ``openai.OpenAI`` client manually.
19
+
20
+ Locked 2026-05-17 — γ-mode integration per founder direction
21
+ ("Cloudflare-стиль: дай ключ, остальное мы делаем").
22
+ """
23
+
24
+ from __future__ import annotations
25
+
26
+ from .core import (
27
+ ProxyStatus,
28
+ activate,
29
+ deactivate,
30
+ headers,
31
+ is_active,
32
+ status,
33
+ url,
34
+ )
35
+
36
+ __version__ = "0.1.0"
37
+
38
+ __all__ = [
39
+ "activate",
40
+ "deactivate",
41
+ "headers",
42
+ "is_active",
43
+ "ProxyStatus",
44
+ "status",
45
+ "url",
46
+ "__version__",
47
+ ]
@@ -0,0 +1,322 @@
1
+ """Tessera SDK core — global activation + per-provider patchers.
2
+
3
+ `activate()` walks a registry of provider-specific patchers. Each patcher is
4
+ opt-in: only fires if the corresponding SDK is importable. So a Python process
5
+ that has only `openai` installed will see `openai` patched and `anthropic`
6
+ silently skipped.
7
+
8
+ Patchers wrap the SDK's primary client constructor(s). After the wrap, every
9
+ new client instance created in the process has its `base_url` pointed at the
10
+ Tessera proxy + `X-Tessera-Key` injected into default headers, while the
11
+ caller's existing provider key (e.g. `sk-...`) stays untouched and flows
12
+ upstream as before.
13
+
14
+ This is intentionally a **global side-effect** per founder direction — same
15
+ shape as `cloudflare.activate()` or `sentry.init()`. Reversal via
16
+ `deactivate()` for test teardown.
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ import dataclasses
22
+ import importlib
23
+ import logging
24
+ import os
25
+ from typing import Any, Callable, Dict, List, Optional, Tuple
26
+
27
+ logger = logging.getLogger("tessera")
28
+
29
+ DEFAULT_PROXY_BASE = "https://api.tesseraai.io/v1"
30
+
31
+ _state: Dict[str, Any] = {
32
+ "active": False,
33
+ "key": None,
34
+ "proxy_base": DEFAULT_PROXY_BASE,
35
+ "feature_tag": None,
36
+ "patched": [], # list of (provider_name, restore_callable)
37
+ }
38
+
39
+
40
+ @dataclasses.dataclass
41
+ class ProxyStatus:
42
+ """Current state of the Tessera SDK patch."""
43
+
44
+ active: bool
45
+ providers_patched: List[str]
46
+ proxy_base: str
47
+ feature_tag: Optional[str]
48
+
49
+
50
+ def url(provider: str) -> str:
51
+ """Return the Tessera proxy URL for ``provider``.
52
+
53
+ Pure helper — no globals required. Use when wiring an SDK client manually
54
+ (e.g. for providers without an official Python SDK such as DeepSeek,
55
+ Together, Fireworks, OpenRouter, Perplexity, Cerebras, xAI).
56
+ """
57
+ base = _state.get("proxy_base") or DEFAULT_PROXY_BASE
58
+ return f"{base.rstrip('/')}/{provider.strip('/')}"
59
+
60
+
61
+ def headers(key: Optional[str] = None) -> Dict[str, str]:
62
+ """Return the headers required to authenticate against Tessera.
63
+
64
+ Reads the activated key by default; pass ``key`` explicitly to override.
65
+ Use alongside :func:`url` for manual SDK wiring.
66
+ """
67
+ resolved_key = key or _state.get("key") or os.environ.get("TESSERA_KEY")
68
+ if not resolved_key:
69
+ raise RuntimeError(
70
+ "Tessera key not set. Call `tessera.activate('tk_...')` first or "
71
+ "pass key= to tessera.headers()."
72
+ )
73
+ result = {"X-Tessera-Key": resolved_key}
74
+ tag = _state.get("feature_tag")
75
+ if tag:
76
+ result["X-Tessera-Feature-Tag"] = tag
77
+ return result
78
+
79
+
80
+ def is_active() -> bool:
81
+ """True if :func:`activate` has been called and patches are installed."""
82
+ return bool(_state.get("active"))
83
+
84
+
85
+ def status() -> ProxyStatus:
86
+ """Snapshot the current SDK state — useful in health checks + logging."""
87
+ return ProxyStatus(
88
+ active=bool(_state.get("active")),
89
+ providers_patched=[name for name, _ in _state.get("patched", [])],
90
+ proxy_base=_state.get("proxy_base") or DEFAULT_PROXY_BASE,
91
+ feature_tag=_state.get("feature_tag"),
92
+ )
93
+
94
+
95
+ def activate(
96
+ key: Optional[str] = None,
97
+ *,
98
+ proxy_base: Optional[str] = None,
99
+ feature_tag: Optional[str] = None,
100
+ ) -> ProxyStatus:
101
+ """Install Tessera patches globally.
102
+
103
+ :param key: Tessera API key (``tk_...``). Falls back to ``TESSERA_KEY``
104
+ environment variable when omitted.
105
+ :param proxy_base: Override the proxy origin. Default
106
+ ``https://api.tesseraai.io/v1``. Used by Tessera staff for staging.
107
+ :param feature_tag: Attach a default ``X-Tessera-Feature-Tag`` header to
108
+ every patched request — useful for per-workload attribution.
109
+ :returns: :class:`ProxyStatus` with the current state.
110
+ :raises RuntimeError: If no key is provided either argument-side or via
111
+ the environment variable.
112
+ """
113
+ resolved_key = key or os.environ.get("TESSERA_KEY")
114
+ if not resolved_key:
115
+ raise RuntimeError(
116
+ "Tessera key not provided. Pass key= to tessera.activate() or set "
117
+ "TESSERA_KEY environment variable."
118
+ )
119
+
120
+ if _state["active"]:
121
+ # Re-activating with new args: deactivate first so we can re-patch with
122
+ # the new state cleanly.
123
+ deactivate()
124
+
125
+ _state["key"] = resolved_key
126
+ _state["proxy_base"] = (proxy_base or DEFAULT_PROXY_BASE).rstrip("/")
127
+ _state["feature_tag"] = feature_tag
128
+ _state["active"] = True
129
+ _state["patched"] = []
130
+
131
+ for patcher in _PATCHERS:
132
+ try:
133
+ restore = patcher()
134
+ if restore is not None:
135
+ _state["patched"].append((patcher.__name__.replace("_patch_", ""), restore))
136
+ except Exception as err: # noqa: BLE001 — best-effort patching
137
+ logger.warning(
138
+ "tessera: failed to patch %s: %s",
139
+ patcher.__name__,
140
+ err,
141
+ )
142
+
143
+ return status()
144
+
145
+
146
+ def deactivate() -> None:
147
+ """Reverse all patches installed by :func:`activate`.
148
+
149
+ SDK constructors are restored to their original values. Safe to call when
150
+ Tessera is not active — becomes a no-op.
151
+ """
152
+ for _provider, restore in reversed(_state.get("patched", [])):
153
+ try:
154
+ restore()
155
+ except Exception as err: # noqa: BLE001
156
+ logger.warning("tessera: failed to restore patch: %s", err)
157
+ _state["active"] = False
158
+ _state["patched"] = []
159
+ _state["key"] = None
160
+ _state["feature_tag"] = None
161
+
162
+
163
+ # ─── per-provider patchers ──────────────────────────────────────────────────
164
+
165
+
166
+ def _safe_import(module_name: str):
167
+ try:
168
+ return importlib.import_module(module_name)
169
+ except ImportError:
170
+ return None
171
+
172
+
173
+ def _wrap_constructor(
174
+ cls: type,
175
+ *,
176
+ base_url_attr: str = "base_url",
177
+ headers_attr: str = "default_headers",
178
+ proxy_path: str,
179
+ ) -> Callable[[], None]:
180
+ """Wrap ``cls.__init__`` so newly-constructed instances route via Tessera.
181
+
182
+ Returns a restore callable that undoes the wrap.
183
+ """
184
+ original_init = cls.__init__
185
+ proxy_url = url(proxy_path)
186
+
187
+ def patched_init(self: Any, *args: Any, **kwargs: Any) -> None:
188
+ # Don't override an explicit base_url override — caller wins.
189
+ if base_url_attr not in kwargs:
190
+ kwargs[base_url_attr] = proxy_url
191
+ # Merge default headers — preserve any caller-provided headers.
192
+ merged_headers: Dict[str, str] = dict(kwargs.get(headers_attr) or {})
193
+ for header_key, header_value in headers().items():
194
+ merged_headers.setdefault(header_key, header_value)
195
+ kwargs[headers_attr] = merged_headers
196
+ original_init(self, *args, **kwargs)
197
+
198
+ cls.__init__ = patched_init # type: ignore[method-assign]
199
+
200
+ def restore() -> None:
201
+ cls.__init__ = original_init # type: ignore[method-assign]
202
+
203
+ return restore
204
+
205
+
206
+ def _patch_openai() -> Optional[Callable[[], None]]:
207
+ mod = _safe_import("openai")
208
+ if mod is None:
209
+ return None
210
+ restorers: List[Callable[[], None]] = []
211
+ for class_name in ("OpenAI", "AsyncOpenAI"):
212
+ cls = getattr(mod, class_name, None)
213
+ if cls is None:
214
+ continue
215
+ restorers.append(
216
+ _wrap_constructor(cls, proxy_path="openai")
217
+ )
218
+
219
+ def restore_all() -> None:
220
+ for r in restorers:
221
+ r()
222
+
223
+ return restore_all if restorers else None
224
+
225
+
226
+ def _patch_anthropic() -> Optional[Callable[[], None]]:
227
+ mod = _safe_import("anthropic")
228
+ if mod is None:
229
+ return None
230
+ restorers: List[Callable[[], None]] = []
231
+ for class_name in ("Anthropic", "AsyncAnthropic"):
232
+ cls = getattr(mod, class_name, None)
233
+ if cls is None:
234
+ continue
235
+ restorers.append(
236
+ _wrap_constructor(cls, proxy_path="anthropic")
237
+ )
238
+
239
+ def restore_all() -> None:
240
+ for r in restorers:
241
+ r()
242
+
243
+ return restore_all if restorers else None
244
+
245
+
246
+ def _patch_mistral() -> Optional[Callable[[], None]]:
247
+ # Newer Mistral SDK (>=1.0) exposes class `Mistral`; legacy uses
248
+ # `MistralClient`. Patch whichever is present.
249
+ mod = _safe_import("mistralai")
250
+ if mod is None:
251
+ return None
252
+ restorers: List[Callable[[], None]] = []
253
+ for class_name in ("Mistral", "MistralClient", "AsyncMistral"):
254
+ cls = getattr(mod, class_name, None)
255
+ if cls is None:
256
+ continue
257
+ # Mistral SDK uses `server_url` rather than `base_url`
258
+ restorers.append(
259
+ _wrap_constructor(
260
+ cls,
261
+ base_url_attr="server_url",
262
+ headers_attr="default_headers",
263
+ proxy_path="mistral",
264
+ )
265
+ )
266
+
267
+ def restore_all() -> None:
268
+ for r in restorers:
269
+ r()
270
+
271
+ return restore_all if restorers else None
272
+
273
+
274
+ def _patch_groq() -> Optional[Callable[[], None]]:
275
+ mod = _safe_import("groq")
276
+ if mod is None:
277
+ return None
278
+ restorers: List[Callable[[], None]] = []
279
+ for class_name in ("Groq", "AsyncGroq"):
280
+ cls = getattr(mod, class_name, None)
281
+ if cls is None:
282
+ continue
283
+ restorers.append(
284
+ _wrap_constructor(cls, proxy_path="groq")
285
+ )
286
+
287
+ def restore_all() -> None:
288
+ for r in restorers:
289
+ r()
290
+
291
+ return restore_all if restorers else None
292
+
293
+
294
+ def _patch_cohere() -> Optional[Callable[[], None]]:
295
+ mod = _safe_import("cohere")
296
+ if mod is None:
297
+ return None
298
+ restorers: List[Callable[[], None]] = []
299
+ # Cohere v5+ SDK class names — patch whichever exist.
300
+ for class_name in ("Client", "ClientV2", "AsyncClient", "AsyncClientV2"):
301
+ cls = getattr(mod, class_name, None)
302
+ if cls is None:
303
+ continue
304
+ # Cohere uses `base_url` keyword
305
+ restorers.append(
306
+ _wrap_constructor(cls, proxy_path="cohere")
307
+ )
308
+
309
+ def restore_all() -> None:
310
+ for r in restorers:
311
+ r()
312
+
313
+ return restore_all if restorers else None
314
+
315
+
316
+ _PATCHERS: Tuple[Callable[[], Optional[Callable[[], None]]], ...] = (
317
+ _patch_openai,
318
+ _patch_anthropic,
319
+ _patch_mistral,
320
+ _patch_groq,
321
+ _patch_cohere,
322
+ )
@@ -0,0 +1,214 @@
1
+ """Tessera SDK core tests — unit-level (no network).
2
+
3
+ We don't have OpenAI/Anthropic installed in the test environment necessarily,
4
+ so tests focus on the pure helpers (url, headers, status, activate/deactivate
5
+ lifecycle) and use a stub class to verify the wrap behaviour without depending
6
+ on a specific provider SDK being importable.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import os
12
+ import sys
13
+ import types
14
+
15
+ import pytest
16
+
17
+ import tessera
18
+ from tessera import core as tessera_core
19
+
20
+
21
+ @pytest.fixture(autouse=True)
22
+ def reset_state():
23
+ """Ensure each test starts fresh."""
24
+ tessera_core.deactivate()
25
+ yield
26
+ tessera_core.deactivate()
27
+
28
+
29
+ def test_default_proxy_base():
30
+ assert tessera_core.DEFAULT_PROXY_BASE == "https://api.tesseraai.io/v1"
31
+
32
+
33
+ def test_url_helper():
34
+ assert tessera.url("openai") == "https://api.tesseraai.io/v1/openai"
35
+ assert tessera.url("anthropic") == "https://api.tesseraai.io/v1/anthropic"
36
+ assert tessera.url("deepseek") == "https://api.tesseraai.io/v1/deepseek"
37
+
38
+
39
+ def test_url_helper_with_leading_slash():
40
+ assert tessera.url("/openai") == "https://api.tesseraai.io/v1/openai"
41
+
42
+
43
+ def test_headers_requires_key():
44
+ with pytest.raises(RuntimeError, match="Tessera key not set"):
45
+ tessera.headers()
46
+
47
+
48
+ def test_headers_with_explicit_key():
49
+ result = tessera.headers(key="tk_test123")
50
+ assert result == {"X-Tessera-Key": "tk_test123"}
51
+
52
+
53
+ def test_headers_reads_env_var(monkeypatch):
54
+ monkeypatch.setenv("TESSERA_KEY", "tk_env_key")
55
+ # Without activate, headers() falls back to env
56
+ result = tessera.headers()
57
+ assert result["X-Tessera-Key"] == "tk_env_key"
58
+
59
+
60
+ def test_activate_requires_key():
61
+ with pytest.raises(RuntimeError, match="Tessera key not provided"):
62
+ tessera.activate()
63
+
64
+
65
+ def test_activate_reads_env_var(monkeypatch):
66
+ monkeypatch.setenv("TESSERA_KEY", "tk_env_activate")
67
+ status = tessera.activate()
68
+ assert status.active is True
69
+ assert tessera.is_active() is True
70
+
71
+
72
+ def test_activate_explicit_key():
73
+ status = tessera.activate("tk_explicit")
74
+ assert status.active is True
75
+ assert tessera.headers() == {"X-Tessera-Key": "tk_explicit"}
76
+
77
+
78
+ def test_activate_feature_tag():
79
+ tessera.activate("tk_test", feature_tag="checkout-summarizer")
80
+ result = tessera.headers()
81
+ assert result["X-Tessera-Key"] == "tk_test"
82
+ assert result["X-Tessera-Feature-Tag"] == "checkout-summarizer"
83
+
84
+
85
+ def test_activate_custom_proxy_base():
86
+ status = tessera.activate("tk_test", proxy_base="https://staging.tesseraai.io/v1")
87
+ assert status.proxy_base == "https://staging.tesseraai.io/v1"
88
+ assert tessera.url("openai") == "https://staging.tesseraai.io/v1/openai"
89
+
90
+
91
+ def test_deactivate_is_safe_when_inactive():
92
+ # Should not raise.
93
+ tessera.deactivate()
94
+ assert tessera.is_active() is False
95
+
96
+
97
+ def test_activate_then_deactivate_lifecycle():
98
+ tessera.activate("tk_test")
99
+ assert tessera.is_active() is True
100
+ tessera.deactivate()
101
+ assert tessera.is_active() is False
102
+ # headers() should now raise again
103
+ with pytest.raises(RuntimeError):
104
+ tessera.headers()
105
+
106
+
107
+ def test_re_activate_replaces_key():
108
+ tessera.activate("tk_first")
109
+ assert tessera.headers()["X-Tessera-Key"] == "tk_first"
110
+ tessera.activate("tk_second")
111
+ assert tessera.headers()["X-Tessera-Key"] == "tk_second"
112
+
113
+
114
+ def test_status_snapshot():
115
+ tessera.activate("tk_test", feature_tag="alpha")
116
+ s = tessera.status()
117
+ assert s.active is True
118
+ assert s.proxy_base == "https://api.tesseraai.io/v1"
119
+ assert s.feature_tag == "alpha"
120
+ # providers_patched may be empty in test env (no SDKs installed), or
121
+ # contain anything that happened to import — just assert shape.
122
+ assert isinstance(s.providers_patched, list)
123
+
124
+
125
+ def test_wrap_constructor_injects_base_url_and_headers(monkeypatch):
126
+ """Drop a fake SDK module + class into sys.modules then verify the
127
+ patcher wraps it correctly. Proves the wrap mechanic without needing the
128
+ real openai package."""
129
+
130
+ captured = {}
131
+
132
+ class FakeClient:
133
+ def __init__(self, api_key=None, base_url=None, default_headers=None, **kwargs):
134
+ captured["api_key"] = api_key
135
+ captured["base_url"] = base_url
136
+ captured["default_headers"] = default_headers
137
+
138
+ fake_module = types.SimpleNamespace(OpenAI=FakeClient)
139
+ monkeypatch.setitem(sys.modules, "openai", fake_module)
140
+
141
+ tessera.activate("tk_wrap_test")
142
+
143
+ # Construct a FakeClient — wrap should inject base_url + Tessera key.
144
+ instance = FakeClient(api_key="sk-user") # noqa: F841 — side-effect captures
145
+ assert captured["base_url"] == "https://api.tesseraai.io/v1/openai"
146
+ assert captured["default_headers"] == {"X-Tessera-Key": "tk_wrap_test"}
147
+ assert captured["api_key"] == "sk-user"
148
+
149
+
150
+ def test_wrap_does_not_override_explicit_base_url(monkeypatch):
151
+ """If caller passes their own base_url, Tessera should NOT override it
152
+ (caller-wins principle for transparent migration)."""
153
+
154
+ captured = {}
155
+
156
+ class FakeClient:
157
+ def __init__(self, api_key=None, base_url=None, default_headers=None, **kwargs):
158
+ captured["base_url"] = base_url
159
+ captured["default_headers"] = default_headers
160
+
161
+ fake_module = types.SimpleNamespace(OpenAI=FakeClient)
162
+ monkeypatch.setitem(sys.modules, "openai", fake_module)
163
+
164
+ tessera.activate("tk_wrap_test")
165
+
166
+ FakeClient(api_key="sk-x", base_url="https://my-custom-proxy.example.com")
167
+ assert captured["base_url"] == "https://my-custom-proxy.example.com"
168
+
169
+
170
+ def test_wrap_preserves_user_headers(monkeypatch):
171
+ """Caller-provided default_headers should merge with Tessera's, not be
172
+ overwritten. Tessera only adds X-Tessera-Key; caller-provided keys win
173
+ on conflict (setdefault semantics)."""
174
+
175
+ captured = {}
176
+
177
+ class FakeClient:
178
+ def __init__(self, api_key=None, base_url=None, default_headers=None, **kwargs):
179
+ captured["default_headers"] = default_headers
180
+
181
+ fake_module = types.SimpleNamespace(OpenAI=FakeClient)
182
+ monkeypatch.setitem(sys.modules, "openai", fake_module)
183
+
184
+ tessera.activate("tk_wrap_test")
185
+ FakeClient(api_key="sk-x", default_headers={"X-User-Trace": "abc123"})
186
+
187
+ headers = captured["default_headers"]
188
+ assert headers["X-User-Trace"] == "abc123" # user header preserved
189
+ assert headers["X-Tessera-Key"] == "tk_wrap_test" # Tessera injected
190
+
191
+
192
+ def test_deactivate_restores_original_constructor(monkeypatch):
193
+ """After deactivate(), newly-created clients should NOT have Tessera
194
+ patches applied. Verifies the restore callable works end-to-end."""
195
+
196
+ captured = {}
197
+ init_calls = []
198
+
199
+ class FakeClient:
200
+ def __init__(self, api_key=None, base_url=None, default_headers=None, **kwargs):
201
+ init_calls.append("called")
202
+ captured["base_url"] = base_url
203
+
204
+ fake_module = types.SimpleNamespace(OpenAI=FakeClient)
205
+ monkeypatch.setitem(sys.modules, "openai", fake_module)
206
+
207
+ tessera.activate("tk_wrap_test")
208
+ FakeClient(api_key="sk-x")
209
+ assert captured["base_url"] == "https://api.tesseraai.io/v1/openai"
210
+
211
+ tessera.deactivate()
212
+ FakeClient(api_key="sk-x") # should now use original __init__
213
+ assert captured["base_url"] is None # no Tessera injection
214
+ assert len(init_calls) == 2