trance 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.
- trance-0.1.0/.gitignore +33 -0
- trance-0.1.0/AGENTS.md +14 -0
- trance-0.1.0/LICENSE +21 -0
- trance-0.1.0/PKG-INFO +229 -0
- trance-0.1.0/README.md +190 -0
- trance-0.1.0/pyproject.toml +47 -0
- trance-0.1.0/src/trance/__init__.py +36 -0
- trance-0.1.0/src/trance/cli_model.py +724 -0
- trance-0.1.0/src/trance/discovery.py +230 -0
- trance-0.1.0/src/trance/models.py +481 -0
- trance-0.1.0/src/trance/sources/__init__.py +7 -0
- trance-0.1.0/src/trance/sources/aws_bedrock.py +221 -0
- trance-0.1.0/src/trance/sources/claude_code.py +120 -0
- trance-0.1.0/src/trance/sources/cloud_api.py +137 -0
- trance-0.1.0/src/trance/sources/codex.py +71 -0
- trance-0.1.0/src/trance/sources/cody.py +88 -0
- trance-0.1.0/src/trance/sources/compatible_api.py +67 -0
- trance-0.1.0/src/trance/sources/copilot.py +100 -0
- trance-0.1.0/src/trance/sources/cursor.py +86 -0
- trance-0.1.0/src/trance/sources/env_api.py +65 -0
- trance-0.1.0/src/trance/sources/gemini_cli.py +128 -0
- trance-0.1.0/src/trance/sources/google_vertex.py +155 -0
- trance-0.1.0/src/trance/sources/grok_consumer.py +126 -0
- trance-0.1.0/src/trance/sources/huggingface_login.py +58 -0
- trance-0.1.0/src/trance/sources/kimi_code.py +110 -0
- trance-0.1.0/src/trance/sources/kiro.py +38 -0
- trance-0.1.0/src/trance/sources/minimax_coding.py +49 -0
- trance-0.1.0/src/trance/sources/mistral_vibe.py +64 -0
- trance-0.1.0/src/trance/sources/opencode.py +130 -0
- trance-0.1.0/src/trance/sources/poe.py +29 -0
- trance-0.1.0/src/trance/sources/qwen_code.py +96 -0
- trance-0.1.0/src/trance/sources/tabnine.py +42 -0
- trance-0.1.0/src/trance/sources/zai.py +53 -0
- trance-0.1.0/src/trance/types.py +63 -0
- trance-0.1.0/tests/test_aws_bedrock_source.py +191 -0
- trance-0.1.0/tests/test_claude_code_source.py +305 -0
- trance-0.1.0/tests/test_cli_model.py +659 -0
- trance-0.1.0/tests/test_cloud_api_source.py +114 -0
- trance-0.1.0/tests/test_codex_source.py +105 -0
- trance-0.1.0/tests/test_cody_source.py +107 -0
- trance-0.1.0/tests/test_compatible_api_source.py +142 -0
- trance-0.1.0/tests/test_copilot_source.py +104 -0
- trance-0.1.0/tests/test_cursor_source.py +47 -0
- trance-0.1.0/tests/test_discovery.py +613 -0
- trance-0.1.0/tests/test_env_api_source.py +66 -0
- trance-0.1.0/tests/test_gemini_cli_source.py +130 -0
- trance-0.1.0/tests/test_google_vertex_source.py +146 -0
- trance-0.1.0/tests/test_grok_consumer_source.py +202 -0
- trance-0.1.0/tests/test_huggingface_login_source.py +50 -0
- trance-0.1.0/tests/test_kimi_code_source.py +94 -0
- trance-0.1.0/tests/test_kiro_source.py +19 -0
- trance-0.1.0/tests/test_local_integration.py +561 -0
- trance-0.1.0/tests/test_minimax_coding_source.py +53 -0
- trance-0.1.0/tests/test_mistral_vibe_source.py +51 -0
- trance-0.1.0/tests/test_models.py +498 -0
- trance-0.1.0/tests/test_opencode_source.py +82 -0
- trance-0.1.0/tests/test_poe_source.py +24 -0
- trance-0.1.0/tests/test_public_api.py +31 -0
- trance-0.1.0/tests/test_qwen_code_source.py +74 -0
- trance-0.1.0/tests/test_security.py +321 -0
- trance-0.1.0/tests/test_tabnine_source.py +39 -0
- trance-0.1.0/tests/test_types.py +48 -0
- trance-0.1.0/tests/test_zai_source.py +42 -0
- trance-0.1.0/uv.lock +3441 -0
trance-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
.dist/
|
|
6
|
+
build/
|
|
7
|
+
dist/
|
|
8
|
+
|
|
9
|
+
# Environments and tooling
|
|
10
|
+
.venv/
|
|
11
|
+
venv/
|
|
12
|
+
.ruff_cache/
|
|
13
|
+
.pytest_cache/
|
|
14
|
+
.mypy_cache/
|
|
15
|
+
.coverage
|
|
16
|
+
|
|
17
|
+
# Local configuration and credentials
|
|
18
|
+
.env
|
|
19
|
+
.env.*
|
|
20
|
+
!.env.example
|
|
21
|
+
*.token
|
|
22
|
+
*.tokens
|
|
23
|
+
*.credentials
|
|
24
|
+
|
|
25
|
+
# IDE and operating system
|
|
26
|
+
.vscode/
|
|
27
|
+
.idea/
|
|
28
|
+
.DS_Store
|
|
29
|
+
Thumbs.db
|
|
30
|
+
|
|
31
|
+
# Local run outputs
|
|
32
|
+
logs/
|
|
33
|
+
outputs/
|
trance-0.1.0/AGENTS.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Development
|
|
2
|
+
|
|
3
|
+
Use `xonsh` and `uv` for project commands. This package is a `src`-layout Python
|
|
4
|
+
library. Keep provider discovery isolated behind small source adapters, keep
|
|
5
|
+
credential values out of logs and fixtures, and keep optional provider SDKs in
|
|
6
|
+
separate extras. The base dependency uses Pydantic AI's OpenAI adapter; install
|
|
7
|
+
a named provider extra only when an adapter needs its native SDK (for example,
|
|
8
|
+
`uv sync --extra dev --extra anthropic`).
|
|
9
|
+
|
|
10
|
+
Set up the development environment with `uv sync --extra dev`. Run the suite
|
|
11
|
+
with `uv run pytest` and lint with `uv run ruff check .`.
|
|
12
|
+
|
|
13
|
+
Do not commit local credentials, environment files, virtual environments, or
|
|
14
|
+
generated build and test artifacts.
|
trance-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 trance contributors
|
|
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.
|
trance-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: trance
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Discover local model provider sessions and expose them through Pydantic AI
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Requires-Python: >=3.11
|
|
8
|
+
Requires-Dist: pydantic-ai-slim[openai]<3,>=2.51.0
|
|
9
|
+
Provides-Extra: anthropic
|
|
10
|
+
Requires-Dist: pydantic-ai-slim[anthropic]<3,>=2.51.0; extra == 'anthropic'
|
|
11
|
+
Provides-Extra: bedrock
|
|
12
|
+
Requires-Dist: pydantic-ai-slim[bedrock]<3,>=2.51.0; extra == 'bedrock'
|
|
13
|
+
Provides-Extra: cerebras
|
|
14
|
+
Requires-Dist: pydantic-ai-slim[cerebras]<3,>=2.51.0; extra == 'cerebras'
|
|
15
|
+
Provides-Extra: cohere
|
|
16
|
+
Requires-Dist: pydantic-ai-slim[cohere]<3,>=2.51.0; extra == 'cohere'
|
|
17
|
+
Provides-Extra: crusoe
|
|
18
|
+
Requires-Dist: pydantic-ai-slim[crusoe]<3,>=2.51.0; extra == 'crusoe'
|
|
19
|
+
Provides-Extra: dev
|
|
20
|
+
Requires-Dist: pytest<10,>=8.3; extra == 'dev'
|
|
21
|
+
Requires-Dist: ruff<1,>=0.12; extra == 'dev'
|
|
22
|
+
Provides-Extra: google
|
|
23
|
+
Requires-Dist: pydantic-ai-slim[google]<3,>=2.51.0; extra == 'google'
|
|
24
|
+
Provides-Extra: groq
|
|
25
|
+
Requires-Dist: pydantic-ai-slim[groq]<3,>=2.51.0; extra == 'groq'
|
|
26
|
+
Provides-Extra: huggingface
|
|
27
|
+
Requires-Dist: pydantic-ai-slim[huggingface]<3,>=2.51.0; extra == 'huggingface'
|
|
28
|
+
Provides-Extra: mistral
|
|
29
|
+
Requires-Dist: pydantic-ai-slim[mistral]<3,>=2.51.0; extra == 'mistral'
|
|
30
|
+
Provides-Extra: openrouter
|
|
31
|
+
Requires-Dist: pydantic-ai-slim[openrouter]<3,>=2.51.0; extra == 'openrouter'
|
|
32
|
+
Provides-Extra: voyageai
|
|
33
|
+
Requires-Dist: pydantic-ai-slim[voyageai]<3,>=2.51.0; extra == 'voyageai'
|
|
34
|
+
Provides-Extra: xai
|
|
35
|
+
Requires-Dist: pydantic-ai-slim[xai]<3,>=2.51.0; extra == 'xai'
|
|
36
|
+
Provides-Extra: zai
|
|
37
|
+
Requires-Dist: pydantic-ai-slim[zai]<3,>=2.51.0; extra == 'zai'
|
|
38
|
+
Description-Content-Type: text/markdown
|
|
39
|
+
|
|
40
|
+
# trance
|
|
41
|
+
|
|
42
|
+
`trance` discovers a limited set of documented credentials and signed-in
|
|
43
|
+
coding tools already configured on your machine, then builds model objects
|
|
44
|
+
using [Pydantic AI](https://ai.pydantic.dev/). It is a small Python library
|
|
45
|
+
for applications that want to reuse supported local provider setups.
|
|
46
|
+
|
|
47
|
+
Consumer subscriptions do not automatically grant general API access. A
|
|
48
|
+
credential being present does not establish that a provider permits using it
|
|
49
|
+
from arbitrary software. `trance` scans only documented local auth state. It
|
|
50
|
+
does not search private browser stores or undocumented application stores;
|
|
51
|
+
raw token strings are not returned or logged, although model objects may retain
|
|
52
|
+
auth internally for requests. Supported CLI adapters may privately stage
|
|
53
|
+
documented saved credentials for a request. Gemini CLI OAuth
|
|
54
|
+
is surfaced only with a warning because its [terms prohibit third-party
|
|
55
|
+
access to the service through its OAuth session and may suspend or terminate
|
|
56
|
+
accounts](https://github.com/google-gemini/gemini-cli/blob/main/docs/resources/tos-privacy.md).
|
|
57
|
+
|
|
58
|
+
## Coverage at a glance
|
|
59
|
+
|
|
60
|
+
| Product | Current supported path |
|
|
61
|
+
| --- | --- |
|
|
62
|
+
| OpenAI Codex | Subscription authentication delegated to the documented Codex CLI/Pydantic AI integration |
|
|
63
|
+
| Claude Code | Subscription authentication delegated to the documented Claude CLI, including a saved CLI login or `CLAUDE_CODE_OAUTH_TOKEN` |
|
|
64
|
+
| Grok Build consumer | Optional integration requiring the installed official `grok` CLI and an authenticated saved session; the CLI adapter validates the session lazily when a request runs |
|
|
65
|
+
| Grok API (xAI) | `XAI_API_KEY` through the regular API-key registry; this is a separate API credential path |
|
|
66
|
+
| Gemini CLI consumer | Optional saved-login integration using the installed `gemini` CLI and `~/.gemini/oauth_creds.json`; discovery emits the documented terms warning and does not provide an opt-in switch |
|
|
67
|
+
| Gemini API | `GOOGLE_API_KEY` or `GEMINI_API_KEY` through the regular API-key registry; this is a separate API credential path |
|
|
68
|
+
| Sourcegraph Cody | Optional saved account login delegated to the installed `cody` CLI |
|
|
69
|
+
| OpenCode | Optional provider-keyed `auth.json` entries for known defaults and model overrides; account/API credentials are delegated to an isolated, no-tools `opencode` CLI |
|
|
70
|
+
| AWS Bedrock | Optional local environment, profile, or SSO credential chain; uses the `bedrock` extra |
|
|
71
|
+
| Google Vertex AI | Optional local Application Default Credentials (ADC); uses the `google` extra |
|
|
72
|
+
|
|
73
|
+
Grok Build and the xAI API are separate credential paths. A consumer account
|
|
74
|
+
or subscription does not by itself provide an xAI API credential. Gemini CLI
|
|
75
|
+
OAuth is a separate, warned integration with Google's terms risk; Gemini API
|
|
76
|
+
keys remain a separate credential path.
|
|
77
|
+
|
|
78
|
+
## Install
|
|
79
|
+
|
|
80
|
+
For a checkout, install the package and development dependencies with:
|
|
81
|
+
|
|
82
|
+
```sh
|
|
83
|
+
uv sync --extra dev
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The core dependency includes Pydantic AI's OpenAI support. Optional extras for
|
|
87
|
+
provider integrations supported by `trance` are `anthropic`, `bedrock`,
|
|
88
|
+
`cerebras`, `cohere`, `crusoe`, `google`, `groq`, `huggingface`, `mistral`,
|
|
89
|
+
`openrouter`, and `xai`. The fixed compatible adapters, including Crusoe, use
|
|
90
|
+
the core OpenAI-compatible model path, so the `crusoe` extra is not required
|
|
91
|
+
for them.
|
|
92
|
+
|
|
93
|
+
## Quick start
|
|
94
|
+
|
|
95
|
+
Sign in with a supported local CLI or configure a documented provider key,
|
|
96
|
+
then scan:
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
from trance.discovery import scan
|
|
100
|
+
from pydantic_ai import Agent
|
|
101
|
+
|
|
102
|
+
found = scan()
|
|
103
|
+
for item in found:
|
|
104
|
+
print(item.provider, item.auth_kind, item.source, item.model_name)
|
|
105
|
+
|
|
106
|
+
# Use a discovered Pydantic AI Model with Agent. Calling run() sends a request.
|
|
107
|
+
agents = [Agent(model=item.model) for item in found]
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`scan()` returns `list[FoundModel]`. Each record identifies the provider,
|
|
111
|
+
authentication kind, discovery source, and model name alongside a Pydantic AI
|
|
112
|
+
`Model`. It constructs objects without sending a request. It does not check
|
|
113
|
+
whether a credential is currently valid, permitted for a particular use, or
|
|
114
|
+
within quota. A `FoundModel` represents a successfully constructed model;
|
|
115
|
+
source adapters that cannot be safely connected to a supported model are
|
|
116
|
+
skipped in the default non-strict mode. Set `strict=True` to raise on a source
|
|
117
|
+
or model construction failure.
|
|
118
|
+
|
|
119
|
+
You can restrict discovery by provider ID, or pass an environment mapping and
|
|
120
|
+
home directory for controlled runs:
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
from pathlib import Path
|
|
124
|
+
from trance.discovery import scan
|
|
125
|
+
|
|
126
|
+
found = scan(
|
|
127
|
+
environ={"OPENAI_API_KEY": "sk-example-not-a-real-key"},
|
|
128
|
+
home=Path("/home/me"),
|
|
129
|
+
providers={"openai"},
|
|
130
|
+
)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Avoid printing or logging the model object: it may retain provider
|
|
134
|
+
authentication material for requests. `FoundModel` and candidate
|
|
135
|
+
representations redact their model and secret fields. The `source` field
|
|
136
|
+
describes where a credential was found and is safe to display.
|
|
137
|
+
|
|
138
|
+
## Discovery sources
|
|
139
|
+
|
|
140
|
+
`scan()` currently registers these adapters. Subscription and account
|
|
141
|
+
integrations are scanned first; ordinary API credentials are scanned after
|
|
142
|
+
them. A subscription login is an integration with the vendor's documented
|
|
143
|
+
account or CLI flow. It is not a general-purpose API key.
|
|
144
|
+
|
|
145
|
+
| Provider or source | What is read | Result and model factory |
|
|
146
|
+
| --- | --- | --- |
|
|
147
|
+
| OpenAI Codex | Bounded metadata from `~/.codex/auth.json` or the file under `CODEX_HOME` (`auth_mode` and the `tokens` shape); token values are never exposed | Subscription candidate; `OpenAICodexModel` resolves the credential |
|
|
148
|
+
| GitHub Copilot | `GITHUB_COPILOT_API_KEY`, `GITHUB_COPILOT_API_TOKEN`, `COPILOT_GITHUB_TOKEN`, or a saved `gh` login | Subscription candidate; `GitHubCopilotModel` |
|
|
149
|
+
| Claude Code | `CLAUDE_CODE_OAUTH_TOKEN`, or a saved first-party login confirmed by `claude auth status` plus `~/.claude/.credentials.json` (or `CLAUDE_CONFIG_DIR/.credentials.json`) | Subscription candidate; text-only Claude CLI model, defaulting to `sonnet` |
|
|
150
|
+
| Poe | `POE_API_KEY` | Subscription candidate; OpenAI-compatible model at Poe's endpoint |
|
|
151
|
+
| MiniMax Coding Plan | `MINIMAX_API_KEY` with the `sk-cp-` prefix and an allowed `MINIMAX_API_HOST` | Subscription candidate; OpenAI-compatible model |
|
|
152
|
+
| Mistral Vibe | `MISTRAL_API_KEY` or `~/.vibe/.env:MISTRAL_API_KEY` | API-key candidate; Mistral model |
|
|
153
|
+
| Qwen Code Coding Plan | `BAILIAN_CODING_PLAN_API_KEY` or supported `~/.qwen/settings.json`, with an `sk-sp-` key | Subscription candidate; OpenAI-compatible model at an allowed Coding Plan endpoint |
|
|
154
|
+
| Hugging Face Hub | Saved login resolved by `huggingface_hub.get_token()` in the real process context | Account candidate; Hugging Face model |
|
|
155
|
+
| Grok Build consumer | Installed `grok` executable and bounded metadata from a non-symlink `~/.grok/auth.json` (or `GROK_HOME/auth.json`) confirming an OIDC record; token values are not retained | Optional account candidate; isolated, text-only Grok CLI model; session validity is checked lazily by the CLI when a request runs, and refreshed auth is promoted back safely |
|
|
156
|
+
| Gemini CLI consumer | Installed `gemini` executable and bounded metadata from `~/.gemini/oauth_creds.json` (or `GEMINI_CLI_HOME/.gemini/oauth_creds.json`) confirming a refresh token; emits a terms warning | Optional account candidate; isolated, text-only Gemini CLI model; no opt-in bypass for the warning |
|
|
157
|
+
| Sourcegraph Cody | Installed `cody` executable and a successful local `cody auth whoami` check with dedicated PAT variables removed | Account candidate; text-only Cody CLI model |
|
|
158
|
+
| OpenCode | Installed `opencode` executable and bounded, provider-keyed `~/.local/share/opencode/auth.json` metadata; recognized OAuth, API-key, and well-known entries only | Account or API-key candidate; isolated `opencode --pure` text-only model with tools disabled; OpenCode manages its own provider-specific OAuth flow |
|
|
159
|
+
| AWS Bedrock | `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY`, or bounded AWS profile credentials/SSO configuration plus a region | Account candidate; Bedrock model through the optional `bedrock` integration |
|
|
160
|
+
| Google Vertex AI | Bounded local ADC metadata from `GOOGLE_APPLICATION_CREDENTIALS` or gcloud ADC, plus a project and optional location | Account candidate; Vertex model through the optional `google` integration |
|
|
161
|
+
| Z.AI | `ZAI_API_KEY` for the general API and `ZAI_CODING_PLAN_API_KEY` for the Coding Plan endpoint | General API-key candidate or Coding Plan subscription candidate; OpenAI-compatible models at separate official endpoints |
|
|
162
|
+
| Fixed compatible API registry | `MOONSHOT_API_KEY`, `NEBIUS_API_KEY`, `DEEPINFRA_TOKEN`/`DEEPINFRA_API_KEY`, `NVIDIA_API_KEY`, `NOVITA_API_KEY`, `AIML_API_KEY`, `OVH_AI_ENDPOINTS_ACCESS_TOKEN`, `HELICONE_API_KEY`, `REQUESTY_API_KEY`, `FEATHERLESS_API_KEY`, `HYPERBOLIC_API_KEY`, `CRUSOE_API_KEY`, `SILICONFLOW_API_KEY`, `VENICE_API_KEY`, `CHUTES_API_KEY`, `AKASH_API_KEY`, `SCW_SECRET_KEY`, `FRIENDLI_API_KEY`, `CLARIFAI_PAT`, `MODEL_API_KEY`, `PARASAIL_API_KEY`, and `NSCALE_API_KEY` | API-key candidates; OpenAI-compatible models at fixed provider endpoints |
|
|
163
|
+
| Validated cloud API registry | Azure OpenAI (`AZURE_OPENAI_API_KEY`, `AZURE_OPENAI_ENDPOINT`, `AZURE_OPENAI_DEPLOYMENT`), Cloudflare Workers AI (`CLOUDFLARE_ACCOUNT_ID`, `CLOUDFLARE_API_KEY`), Databricks (`DATABRICKS_TOKEN`, `DATABRICKS_HOST`, `DATABRICKS_MODEL`), and DashScope (`DASHSCOPE_API_KEY`, optional `DASHSCOPE_BASE_URL`) | API-key candidates; OpenAI-compatible models with provider-owned HTTPS endpoints |
|
|
164
|
+
| Generic API-key registry | `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GOOGLE_API_KEY`/`GEMINI_API_KEY`, `XAI_API_KEY`, `GROQ_API_KEY`, `MISTRAL_API_KEY`, `COHERE_API_KEY`, `CEREBRAS_API_KEY`, `HF_TOKEN`/`HUGGINGFACE_API_KEY`, `OPENROUTER_API_KEY`, `DEEPSEEK_API_KEY`, `FIREWORKS_API_KEY`, `TOGETHER_API_KEY`, `PERPLEXITY_API_KEY`, `SAMBANOVA_API_KEY` | API-key candidates; the Pydantic AI provider factory, with documented OpenAI-compatible fallbacks where available |
|
|
165
|
+
|
|
166
|
+
The fixed compatible registry currently covers 22 API-key providers, including
|
|
167
|
+
AkashML, Scaleway, Friendli, Clarifai, Meta Model API, Parasail, and Nscale.
|
|
168
|
+
These credentials are ordinary API credentials, not subscription or account-
|
|
169
|
+
login integrations.
|
|
170
|
+
|
|
171
|
+
The model construction path supports the registered provider IDs: API and
|
|
172
|
+
account integrations use `trance.models.build_model()`, while Claude Code,
|
|
173
|
+
Grok Build, Gemini CLI, Cody, and OpenCode use text-only CLI adapters. It creates Pydantic AI model objects
|
|
174
|
+
without sending a request and loads optional provider dependencies lazily. Use
|
|
175
|
+
`TRANCE_MODEL_<PROVIDER>` variables to override defaults where the source
|
|
176
|
+
supports them. To use the optional Grok Build integration, install the
|
|
177
|
+
official `grok` CLI and authenticate it with `grok login` (or
|
|
178
|
+
`grok login --device-auth` on a headless machine). Discovery only checks the
|
|
179
|
+
CLI and bounded OIDC metadata in the saved `auth.json`; it does not claim that
|
|
180
|
+
the session is valid until the CLI handles a model request. The optional Gemini
|
|
181
|
+
CLI integration similarly requires the official `gemini` CLI and a saved
|
|
182
|
+
`oauth_creds.json`; discovery emits its terms warning whenever it finds one.
|
|
183
|
+
The optional Cody and OpenCode integrations likewise require their respective
|
|
184
|
+
CLIs to be installed; discovery performs only their documented local login or
|
|
185
|
+
metadata checks and does not make a model request.
|
|
186
|
+
|
|
187
|
+
Discovery performs no live model API validation and does not establish that a
|
|
188
|
+
credential is valid, permitted for a particular use, or within quota. It may
|
|
189
|
+
inspect explicitly supported local files, including bounded Codex auth metadata,
|
|
190
|
+
Grok OIDC metadata, Gemini OAuth metadata, OpenCode auth metadata, bounded AWS
|
|
191
|
+
profiles, and local Vertex ADC metadata, run `cody auth whoami` and `gh auth
|
|
192
|
+
status` and (when materializing a Copilot candidate) `gh auth token`, resolve a
|
|
193
|
+
saved Hugging Face token, and run `claude auth status` plus a credentials-file
|
|
194
|
+
existence check to detect a saved Claude subscription login. The Claude CLI is not used for a model request until a
|
|
195
|
+
Pydantic AI request is made. Its adapter supports text requests only; it does
|
|
196
|
+
not support Pydantic AI tools or structured output.
|
|
197
|
+
|
|
198
|
+
Cursor, Kiro, Tabnine, and Kimi Code adapters remain source-only and are
|
|
199
|
+
intentionally excluded from `scan()` results because they have no safe,
|
|
200
|
+
supported model bridge. In particular, their CLIs can expose hooks,
|
|
201
|
+
integrations, or credential flows that cannot be constrained to the supported
|
|
202
|
+
text-only request path.
|
|
203
|
+
|
|
204
|
+
Read the vendors' documentation for their authentication and use conditions:
|
|
205
|
+
[Codex CLI sign-in](https://help.openai.com/en/articles/11381614-api-codex-cli-and-sign-in-with-chatgpt),
|
|
206
|
+
[Copilot CLI authentication](https://docs.github.com/en/copilot/how-tos/copilot-cli/set-up-copilot-cli/authenticate-copilot-cli),
|
|
207
|
+
[Claude Code authentication](https://code.claude.com/docs/en/iam),
|
|
208
|
+
[Grok Build overview](https://docs.x.ai/build/overview),
|
|
209
|
+
[Grok Build CLI reference](https://docs.x.ai/build/cli/reference),
|
|
210
|
+
[Sourcegraph Cody CLI](https://sourcegraph.com/docs/cody/overview),
|
|
211
|
+
[OpenCode documentation](https://opencode.ai/docs/),
|
|
212
|
+
[Amazon Bedrock authentication](https://docs.aws.amazon.com/bedrock/latest/userguide/security-iam.html),
|
|
213
|
+
[Google Vertex AI authentication](https://cloud.google.com/docs/authentication/application-default-credentials),
|
|
214
|
+
[Z.AI documentation](https://docs.z.ai/),
|
|
215
|
+
[Qwen Code Coding Plan](https://github.com/QwenLM/qwen-code/blob/main/docs/users/configuration/model-providers.md),
|
|
216
|
+
[Hugging Face Hub login](https://huggingface.co/docs/huggingface_hub/quick-start#login),
|
|
217
|
+
[Poe API keys](https://creator.poe.com/docs/external-applications),
|
|
218
|
+
[MiniMax API](https://platform.minimax.io/docs/api-reference),
|
|
219
|
+
[Mistral Vibe](https://docs.mistral.ai/capabilities/vibe/).
|
|
220
|
+
|
|
221
|
+
## Development
|
|
222
|
+
|
|
223
|
+
This repository uses `uv` and `xonsh`:
|
|
224
|
+
|
|
225
|
+
```sh
|
|
226
|
+
uv sync --extra dev
|
|
227
|
+
uv run pytest
|
|
228
|
+
uv run ruff check .
|
|
229
|
+
```
|
trance-0.1.0/README.md
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# trance
|
|
2
|
+
|
|
3
|
+
`trance` discovers a limited set of documented credentials and signed-in
|
|
4
|
+
coding tools already configured on your machine, then builds model objects
|
|
5
|
+
using [Pydantic AI](https://ai.pydantic.dev/). It is a small Python library
|
|
6
|
+
for applications that want to reuse supported local provider setups.
|
|
7
|
+
|
|
8
|
+
Consumer subscriptions do not automatically grant general API access. A
|
|
9
|
+
credential being present does not establish that a provider permits using it
|
|
10
|
+
from arbitrary software. `trance` scans only documented local auth state. It
|
|
11
|
+
does not search private browser stores or undocumented application stores;
|
|
12
|
+
raw token strings are not returned or logged, although model objects may retain
|
|
13
|
+
auth internally for requests. Supported CLI adapters may privately stage
|
|
14
|
+
documented saved credentials for a request. Gemini CLI OAuth
|
|
15
|
+
is surfaced only with a warning because its [terms prohibit third-party
|
|
16
|
+
access to the service through its OAuth session and may suspend or terminate
|
|
17
|
+
accounts](https://github.com/google-gemini/gemini-cli/blob/main/docs/resources/tos-privacy.md).
|
|
18
|
+
|
|
19
|
+
## Coverage at a glance
|
|
20
|
+
|
|
21
|
+
| Product | Current supported path |
|
|
22
|
+
| --- | --- |
|
|
23
|
+
| OpenAI Codex | Subscription authentication delegated to the documented Codex CLI/Pydantic AI integration |
|
|
24
|
+
| Claude Code | Subscription authentication delegated to the documented Claude CLI, including a saved CLI login or `CLAUDE_CODE_OAUTH_TOKEN` |
|
|
25
|
+
| Grok Build consumer | Optional integration requiring the installed official `grok` CLI and an authenticated saved session; the CLI adapter validates the session lazily when a request runs |
|
|
26
|
+
| Grok API (xAI) | `XAI_API_KEY` through the regular API-key registry; this is a separate API credential path |
|
|
27
|
+
| Gemini CLI consumer | Optional saved-login integration using the installed `gemini` CLI and `~/.gemini/oauth_creds.json`; discovery emits the documented terms warning and does not provide an opt-in switch |
|
|
28
|
+
| Gemini API | `GOOGLE_API_KEY` or `GEMINI_API_KEY` through the regular API-key registry; this is a separate API credential path |
|
|
29
|
+
| Sourcegraph Cody | Optional saved account login delegated to the installed `cody` CLI |
|
|
30
|
+
| OpenCode | Optional provider-keyed `auth.json` entries for known defaults and model overrides; account/API credentials are delegated to an isolated, no-tools `opencode` CLI |
|
|
31
|
+
| AWS Bedrock | Optional local environment, profile, or SSO credential chain; uses the `bedrock` extra |
|
|
32
|
+
| Google Vertex AI | Optional local Application Default Credentials (ADC); uses the `google` extra |
|
|
33
|
+
|
|
34
|
+
Grok Build and the xAI API are separate credential paths. A consumer account
|
|
35
|
+
or subscription does not by itself provide an xAI API credential. Gemini CLI
|
|
36
|
+
OAuth is a separate, warned integration with Google's terms risk; Gemini API
|
|
37
|
+
keys remain a separate credential path.
|
|
38
|
+
|
|
39
|
+
## Install
|
|
40
|
+
|
|
41
|
+
For a checkout, install the package and development dependencies with:
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
uv sync --extra dev
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The core dependency includes Pydantic AI's OpenAI support. Optional extras for
|
|
48
|
+
provider integrations supported by `trance` are `anthropic`, `bedrock`,
|
|
49
|
+
`cerebras`, `cohere`, `crusoe`, `google`, `groq`, `huggingface`, `mistral`,
|
|
50
|
+
`openrouter`, and `xai`. The fixed compatible adapters, including Crusoe, use
|
|
51
|
+
the core OpenAI-compatible model path, so the `crusoe` extra is not required
|
|
52
|
+
for them.
|
|
53
|
+
|
|
54
|
+
## Quick start
|
|
55
|
+
|
|
56
|
+
Sign in with a supported local CLI or configure a documented provider key,
|
|
57
|
+
then scan:
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
from trance.discovery import scan
|
|
61
|
+
from pydantic_ai import Agent
|
|
62
|
+
|
|
63
|
+
found = scan()
|
|
64
|
+
for item in found:
|
|
65
|
+
print(item.provider, item.auth_kind, item.source, item.model_name)
|
|
66
|
+
|
|
67
|
+
# Use a discovered Pydantic AI Model with Agent. Calling run() sends a request.
|
|
68
|
+
agents = [Agent(model=item.model) for item in found]
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`scan()` returns `list[FoundModel]`. Each record identifies the provider,
|
|
72
|
+
authentication kind, discovery source, and model name alongside a Pydantic AI
|
|
73
|
+
`Model`. It constructs objects without sending a request. It does not check
|
|
74
|
+
whether a credential is currently valid, permitted for a particular use, or
|
|
75
|
+
within quota. A `FoundModel` represents a successfully constructed model;
|
|
76
|
+
source adapters that cannot be safely connected to a supported model are
|
|
77
|
+
skipped in the default non-strict mode. Set `strict=True` to raise on a source
|
|
78
|
+
or model construction failure.
|
|
79
|
+
|
|
80
|
+
You can restrict discovery by provider ID, or pass an environment mapping and
|
|
81
|
+
home directory for controlled runs:
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
from pathlib import Path
|
|
85
|
+
from trance.discovery import scan
|
|
86
|
+
|
|
87
|
+
found = scan(
|
|
88
|
+
environ={"OPENAI_API_KEY": "sk-example-not-a-real-key"},
|
|
89
|
+
home=Path("/home/me"),
|
|
90
|
+
providers={"openai"},
|
|
91
|
+
)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Avoid printing or logging the model object: it may retain provider
|
|
95
|
+
authentication material for requests. `FoundModel` and candidate
|
|
96
|
+
representations redact their model and secret fields. The `source` field
|
|
97
|
+
describes where a credential was found and is safe to display.
|
|
98
|
+
|
|
99
|
+
## Discovery sources
|
|
100
|
+
|
|
101
|
+
`scan()` currently registers these adapters. Subscription and account
|
|
102
|
+
integrations are scanned first; ordinary API credentials are scanned after
|
|
103
|
+
them. A subscription login is an integration with the vendor's documented
|
|
104
|
+
account or CLI flow. It is not a general-purpose API key.
|
|
105
|
+
|
|
106
|
+
| Provider or source | What is read | Result and model factory |
|
|
107
|
+
| --- | --- | --- |
|
|
108
|
+
| OpenAI Codex | Bounded metadata from `~/.codex/auth.json` or the file under `CODEX_HOME` (`auth_mode` and the `tokens` shape); token values are never exposed | Subscription candidate; `OpenAICodexModel` resolves the credential |
|
|
109
|
+
| GitHub Copilot | `GITHUB_COPILOT_API_KEY`, `GITHUB_COPILOT_API_TOKEN`, `COPILOT_GITHUB_TOKEN`, or a saved `gh` login | Subscription candidate; `GitHubCopilotModel` |
|
|
110
|
+
| Claude Code | `CLAUDE_CODE_OAUTH_TOKEN`, or a saved first-party login confirmed by `claude auth status` plus `~/.claude/.credentials.json` (or `CLAUDE_CONFIG_DIR/.credentials.json`) | Subscription candidate; text-only Claude CLI model, defaulting to `sonnet` |
|
|
111
|
+
| Poe | `POE_API_KEY` | Subscription candidate; OpenAI-compatible model at Poe's endpoint |
|
|
112
|
+
| MiniMax Coding Plan | `MINIMAX_API_KEY` with the `sk-cp-` prefix and an allowed `MINIMAX_API_HOST` | Subscription candidate; OpenAI-compatible model |
|
|
113
|
+
| Mistral Vibe | `MISTRAL_API_KEY` or `~/.vibe/.env:MISTRAL_API_KEY` | API-key candidate; Mistral model |
|
|
114
|
+
| Qwen Code Coding Plan | `BAILIAN_CODING_PLAN_API_KEY` or supported `~/.qwen/settings.json`, with an `sk-sp-` key | Subscription candidate; OpenAI-compatible model at an allowed Coding Plan endpoint |
|
|
115
|
+
| Hugging Face Hub | Saved login resolved by `huggingface_hub.get_token()` in the real process context | Account candidate; Hugging Face model |
|
|
116
|
+
| Grok Build consumer | Installed `grok` executable and bounded metadata from a non-symlink `~/.grok/auth.json` (or `GROK_HOME/auth.json`) confirming an OIDC record; token values are not retained | Optional account candidate; isolated, text-only Grok CLI model; session validity is checked lazily by the CLI when a request runs, and refreshed auth is promoted back safely |
|
|
117
|
+
| Gemini CLI consumer | Installed `gemini` executable and bounded metadata from `~/.gemini/oauth_creds.json` (or `GEMINI_CLI_HOME/.gemini/oauth_creds.json`) confirming a refresh token; emits a terms warning | Optional account candidate; isolated, text-only Gemini CLI model; no opt-in bypass for the warning |
|
|
118
|
+
| Sourcegraph Cody | Installed `cody` executable and a successful local `cody auth whoami` check with dedicated PAT variables removed | Account candidate; text-only Cody CLI model |
|
|
119
|
+
| OpenCode | Installed `opencode` executable and bounded, provider-keyed `~/.local/share/opencode/auth.json` metadata; recognized OAuth, API-key, and well-known entries only | Account or API-key candidate; isolated `opencode --pure` text-only model with tools disabled; OpenCode manages its own provider-specific OAuth flow |
|
|
120
|
+
| AWS Bedrock | `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY`, or bounded AWS profile credentials/SSO configuration plus a region | Account candidate; Bedrock model through the optional `bedrock` integration |
|
|
121
|
+
| Google Vertex AI | Bounded local ADC metadata from `GOOGLE_APPLICATION_CREDENTIALS` or gcloud ADC, plus a project and optional location | Account candidate; Vertex model through the optional `google` integration |
|
|
122
|
+
| Z.AI | `ZAI_API_KEY` for the general API and `ZAI_CODING_PLAN_API_KEY` for the Coding Plan endpoint | General API-key candidate or Coding Plan subscription candidate; OpenAI-compatible models at separate official endpoints |
|
|
123
|
+
| Fixed compatible API registry | `MOONSHOT_API_KEY`, `NEBIUS_API_KEY`, `DEEPINFRA_TOKEN`/`DEEPINFRA_API_KEY`, `NVIDIA_API_KEY`, `NOVITA_API_KEY`, `AIML_API_KEY`, `OVH_AI_ENDPOINTS_ACCESS_TOKEN`, `HELICONE_API_KEY`, `REQUESTY_API_KEY`, `FEATHERLESS_API_KEY`, `HYPERBOLIC_API_KEY`, `CRUSOE_API_KEY`, `SILICONFLOW_API_KEY`, `VENICE_API_KEY`, `CHUTES_API_KEY`, `AKASH_API_KEY`, `SCW_SECRET_KEY`, `FRIENDLI_API_KEY`, `CLARIFAI_PAT`, `MODEL_API_KEY`, `PARASAIL_API_KEY`, and `NSCALE_API_KEY` | API-key candidates; OpenAI-compatible models at fixed provider endpoints |
|
|
124
|
+
| Validated cloud API registry | Azure OpenAI (`AZURE_OPENAI_API_KEY`, `AZURE_OPENAI_ENDPOINT`, `AZURE_OPENAI_DEPLOYMENT`), Cloudflare Workers AI (`CLOUDFLARE_ACCOUNT_ID`, `CLOUDFLARE_API_KEY`), Databricks (`DATABRICKS_TOKEN`, `DATABRICKS_HOST`, `DATABRICKS_MODEL`), and DashScope (`DASHSCOPE_API_KEY`, optional `DASHSCOPE_BASE_URL`) | API-key candidates; OpenAI-compatible models with provider-owned HTTPS endpoints |
|
|
125
|
+
| Generic API-key registry | `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GOOGLE_API_KEY`/`GEMINI_API_KEY`, `XAI_API_KEY`, `GROQ_API_KEY`, `MISTRAL_API_KEY`, `COHERE_API_KEY`, `CEREBRAS_API_KEY`, `HF_TOKEN`/`HUGGINGFACE_API_KEY`, `OPENROUTER_API_KEY`, `DEEPSEEK_API_KEY`, `FIREWORKS_API_KEY`, `TOGETHER_API_KEY`, `PERPLEXITY_API_KEY`, `SAMBANOVA_API_KEY` | API-key candidates; the Pydantic AI provider factory, with documented OpenAI-compatible fallbacks where available |
|
|
126
|
+
|
|
127
|
+
The fixed compatible registry currently covers 22 API-key providers, including
|
|
128
|
+
AkashML, Scaleway, Friendli, Clarifai, Meta Model API, Parasail, and Nscale.
|
|
129
|
+
These credentials are ordinary API credentials, not subscription or account-
|
|
130
|
+
login integrations.
|
|
131
|
+
|
|
132
|
+
The model construction path supports the registered provider IDs: API and
|
|
133
|
+
account integrations use `trance.models.build_model()`, while Claude Code,
|
|
134
|
+
Grok Build, Gemini CLI, Cody, and OpenCode use text-only CLI adapters. It creates Pydantic AI model objects
|
|
135
|
+
without sending a request and loads optional provider dependencies lazily. Use
|
|
136
|
+
`TRANCE_MODEL_<PROVIDER>` variables to override defaults where the source
|
|
137
|
+
supports them. To use the optional Grok Build integration, install the
|
|
138
|
+
official `grok` CLI and authenticate it with `grok login` (or
|
|
139
|
+
`grok login --device-auth` on a headless machine). Discovery only checks the
|
|
140
|
+
CLI and bounded OIDC metadata in the saved `auth.json`; it does not claim that
|
|
141
|
+
the session is valid until the CLI handles a model request. The optional Gemini
|
|
142
|
+
CLI integration similarly requires the official `gemini` CLI and a saved
|
|
143
|
+
`oauth_creds.json`; discovery emits its terms warning whenever it finds one.
|
|
144
|
+
The optional Cody and OpenCode integrations likewise require their respective
|
|
145
|
+
CLIs to be installed; discovery performs only their documented local login or
|
|
146
|
+
metadata checks and does not make a model request.
|
|
147
|
+
|
|
148
|
+
Discovery performs no live model API validation and does not establish that a
|
|
149
|
+
credential is valid, permitted for a particular use, or within quota. It may
|
|
150
|
+
inspect explicitly supported local files, including bounded Codex auth metadata,
|
|
151
|
+
Grok OIDC metadata, Gemini OAuth metadata, OpenCode auth metadata, bounded AWS
|
|
152
|
+
profiles, and local Vertex ADC metadata, run `cody auth whoami` and `gh auth
|
|
153
|
+
status` and (when materializing a Copilot candidate) `gh auth token`, resolve a
|
|
154
|
+
saved Hugging Face token, and run `claude auth status` plus a credentials-file
|
|
155
|
+
existence check to detect a saved Claude subscription login. The Claude CLI is not used for a model request until a
|
|
156
|
+
Pydantic AI request is made. Its adapter supports text requests only; it does
|
|
157
|
+
not support Pydantic AI tools or structured output.
|
|
158
|
+
|
|
159
|
+
Cursor, Kiro, Tabnine, and Kimi Code adapters remain source-only and are
|
|
160
|
+
intentionally excluded from `scan()` results because they have no safe,
|
|
161
|
+
supported model bridge. In particular, their CLIs can expose hooks,
|
|
162
|
+
integrations, or credential flows that cannot be constrained to the supported
|
|
163
|
+
text-only request path.
|
|
164
|
+
|
|
165
|
+
Read the vendors' documentation for their authentication and use conditions:
|
|
166
|
+
[Codex CLI sign-in](https://help.openai.com/en/articles/11381614-api-codex-cli-and-sign-in-with-chatgpt),
|
|
167
|
+
[Copilot CLI authentication](https://docs.github.com/en/copilot/how-tos/copilot-cli/set-up-copilot-cli/authenticate-copilot-cli),
|
|
168
|
+
[Claude Code authentication](https://code.claude.com/docs/en/iam),
|
|
169
|
+
[Grok Build overview](https://docs.x.ai/build/overview),
|
|
170
|
+
[Grok Build CLI reference](https://docs.x.ai/build/cli/reference),
|
|
171
|
+
[Sourcegraph Cody CLI](https://sourcegraph.com/docs/cody/overview),
|
|
172
|
+
[OpenCode documentation](https://opencode.ai/docs/),
|
|
173
|
+
[Amazon Bedrock authentication](https://docs.aws.amazon.com/bedrock/latest/userguide/security-iam.html),
|
|
174
|
+
[Google Vertex AI authentication](https://cloud.google.com/docs/authentication/application-default-credentials),
|
|
175
|
+
[Z.AI documentation](https://docs.z.ai/),
|
|
176
|
+
[Qwen Code Coding Plan](https://github.com/QwenLM/qwen-code/blob/main/docs/users/configuration/model-providers.md),
|
|
177
|
+
[Hugging Face Hub login](https://huggingface.co/docs/huggingface_hub/quick-start#login),
|
|
178
|
+
[Poe API keys](https://creator.poe.com/docs/external-applications),
|
|
179
|
+
[MiniMax API](https://platform.minimax.io/docs/api-reference),
|
|
180
|
+
[Mistral Vibe](https://docs.mistral.ai/capabilities/vibe/).
|
|
181
|
+
|
|
182
|
+
## Development
|
|
183
|
+
|
|
184
|
+
This repository uses `uv` and `xonsh`:
|
|
185
|
+
|
|
186
|
+
```sh
|
|
187
|
+
uv sync --extra dev
|
|
188
|
+
uv run pytest
|
|
189
|
+
uv run ruff check .
|
|
190
|
+
```
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.27"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "trance"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Discover local model provider sessions and expose them through Pydantic AI"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
dependencies = [
|
|
13
|
+
"pydantic-ai-slim[openai]>=2.51.0,<3",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
[project.optional-dependencies]
|
|
17
|
+
anthropic = ["pydantic-ai-slim[anthropic]>=2.51.0,<3"]
|
|
18
|
+
bedrock = ["pydantic-ai-slim[bedrock]>=2.51.0,<3"]
|
|
19
|
+
cerebras = ["pydantic-ai-slim[cerebras]>=2.51.0,<3"]
|
|
20
|
+
cohere = ["pydantic-ai-slim[cohere]>=2.51.0,<3"]
|
|
21
|
+
crusoe = ["pydantic-ai-slim[crusoe]>=2.51.0,<3"]
|
|
22
|
+
google = ["pydantic-ai-slim[google]>=2.51.0,<3"]
|
|
23
|
+
groq = ["pydantic-ai-slim[groq]>=2.51.0,<3"]
|
|
24
|
+
huggingface = ["pydantic-ai-slim[huggingface]>=2.51.0,<3"]
|
|
25
|
+
mistral = ["pydantic-ai-slim[mistral]>=2.51.0,<3"]
|
|
26
|
+
openrouter = ["pydantic-ai-slim[openrouter]>=2.51.0,<3"]
|
|
27
|
+
voyageai = ["pydantic-ai-slim[voyageai]>=2.51.0,<3"]
|
|
28
|
+
xai = ["pydantic-ai-slim[xai]>=2.51.0,<3"]
|
|
29
|
+
zai = ["pydantic-ai-slim[zai]>=2.51.0,<3"]
|
|
30
|
+
dev = [
|
|
31
|
+
"pytest>=8.3,<10",
|
|
32
|
+
"ruff>=0.12,<1",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[tool.hatch.build.targets.wheel]
|
|
36
|
+
packages = ["src/trance"]
|
|
37
|
+
|
|
38
|
+
[tool.pytest.ini_options]
|
|
39
|
+
testpaths = ["tests"]
|
|
40
|
+
addopts = "-q"
|
|
41
|
+
|
|
42
|
+
[tool.ruff]
|
|
43
|
+
line-length = 100
|
|
44
|
+
target-version = "py311"
|
|
45
|
+
|
|
46
|
+
[tool.ruff.lint]
|
|
47
|
+
select = ["E", "F", "I", "UP"]
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""Discover local model sessions and expose them through a stable API.
|
|
2
|
+
|
|
3
|
+
The package root intentionally avoids importing discovery and model adapters
|
|
4
|
+
until a caller uses them. This keeps a plain ``import trance`` inexpensive.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from importlib import import_module
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
__version__ = "0.1.0"
|
|
13
|
+
|
|
14
|
+
_EXPORTS = {
|
|
15
|
+
"scan": ("trance.discovery", "scan"),
|
|
16
|
+
"clients": ("trance.discovery", "clients"),
|
|
17
|
+
"Candidate": ("trance.types", "Candidate"),
|
|
18
|
+
"FoundModel": ("trance.types", "FoundModel"),
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
__all__ = ["__version__", *_EXPORTS]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def __getattr__(name: str) -> Any:
|
|
25
|
+
"""Load public API objects only when requested."""
|
|
26
|
+
try:
|
|
27
|
+
module_name, attribute = _EXPORTS[name]
|
|
28
|
+
except KeyError:
|
|
29
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}") from None
|
|
30
|
+
value = getattr(import_module(module_name), attribute)
|
|
31
|
+
globals()[name] = value
|
|
32
|
+
return value
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def __dir__() -> list[str]:
|
|
36
|
+
return sorted(set(globals()) | set(__all__))
|