blazing-agents 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.
- blazing_agents-0.1.0/.github/workflows/ci.yml +45 -0
- blazing_agents-0.1.0/.github/workflows/publish.yml +27 -0
- blazing_agents-0.1.0/.gitignore +7 -0
- blazing_agents-0.1.0/LICENSE +21 -0
- blazing_agents-0.1.0/PKG-INFO +340 -0
- blazing_agents-0.1.0/README.md +327 -0
- blazing_agents-0.1.0/pyproject.toml +55 -0
- blazing_agents-0.1.0/scripts/run_compatibility.py +56 -0
- blazing_agents-0.1.0/scripts/run_integration.py +169 -0
- blazing_agents-0.1.0/scripts/run_tests.py +188 -0
- blazing_agents-0.1.0/scripts/run_typechecks.py +68 -0
- blazing_agents-0.1.0/src/blazing_agents/__init__.py +312 -0
- blazing_agents-0.1.0/src/blazing_agents/_chat.py +138 -0
- blazing_agents-0.1.0/src/blazing_agents/_client.py +782 -0
- blazing_agents-0.1.0/src/blazing_agents/_completion.py +165 -0
- blazing_agents-0.1.0/src/blazing_agents/_downloads.py +105 -0
- blazing_agents-0.1.0/src/blazing_agents/_errors.py +104 -0
- blazing_agents-0.1.0/src/blazing_agents/_models.py +883 -0
- blazing_agents-0.1.0/src/blazing_agents/_object.py +229 -0
- blazing_agents-0.1.0/src/blazing_agents/_resources.py +4616 -0
- blazing_agents-0.1.0/src/blazing_agents/_responses.py +16 -0
- blazing_agents-0.1.0/src/blazing_agents/_transport.py +784 -0
- blazing_agents-0.1.0/src/blazing_agents/_types.py +479 -0
- blazing_agents-0.1.0/src/blazing_agents/_version.py +3 -0
- blazing_agents-0.1.0/src/blazing_agents/py.typed +1 -0
- blazing_agents-0.1.0/tests/test_clients.py +6798 -0
- blazing_agents-0.1.0/tests/test_response_observation.py +471 -0
- blazing_agents-0.1.0/typing/invalid_agent_configuration.py +7 -0
- blazing_agents-0.1.0/typing/invalid_ambiguous.py +15 -0
- blazing_agents-0.1.0/typing/invalid_artifacts_user_id.py +3 -0
- blazing_agents-0.1.0/typing/invalid_chat_regenerate.py +7 -0
- blazing_agents-0.1.0/typing/invalid_chat_regenerate_client.py +17 -0
- blazing_agents-0.1.0/typing/invalid_chat_version.py +8 -0
- blazing_agents-0.1.0/typing/invalid_request_literal.py +6 -0
- blazing_agents-0.1.0/typing/invalid_request_unknown.py +6 -0
- blazing_agents-0.1.0/typing/invalid_simultaneous.py +31 -0
- blazing_agents-0.1.0/typing/invalid_workspace_none.py +11 -0
- blazing_agents-0.1.0/typing/invalid_workspace_none_request.py +7 -0
- blazing_agents-0.1.0/typing/valid.py +342 -0
- blazing_agents-0.1.0/uv.lock +663 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
concurrency:
|
|
12
|
+
group: ci-${{ github.workflow }}-${{ github.ref }}
|
|
13
|
+
cancel-in-progress: true
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
check:
|
|
17
|
+
name: Check
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
timeout-minutes: 15
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v6
|
|
22
|
+
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
23
|
+
with:
|
|
24
|
+
enable-cache: true
|
|
25
|
+
- run: uv sync --locked
|
|
26
|
+
- run: uv run ruff check .
|
|
27
|
+
- run: uv run ruff format --check .
|
|
28
|
+
- run: uv run python scripts/run_typechecks.py
|
|
29
|
+
- run: uv run python scripts/run_tests.py
|
|
30
|
+
|
|
31
|
+
compatibility:
|
|
32
|
+
name: Python ${{ matrix.python-version }}
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
timeout-minutes: 15
|
|
35
|
+
strategy:
|
|
36
|
+
fail-fast: false
|
|
37
|
+
matrix:
|
|
38
|
+
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
|
39
|
+
steps:
|
|
40
|
+
- uses: actions/checkout@v6
|
|
41
|
+
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
42
|
+
with:
|
|
43
|
+
enable-cache: true
|
|
44
|
+
python-version: ${{ matrix.python-version }}
|
|
45
|
+
- run: uv run --python ${{ matrix.python-version }} python scripts/run_compatibility.py
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
publish:
|
|
12
|
+
if: ${{ !github.event.release.prerelease }}
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
timeout-minutes: 15
|
|
15
|
+
environment: pypi
|
|
16
|
+
permissions:
|
|
17
|
+
id-token: write
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v6
|
|
20
|
+
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
21
|
+
- name: Verify release tag matches package version
|
|
22
|
+
run: >-
|
|
23
|
+
python -c 'import os, tomllib;
|
|
24
|
+
version = tomllib.load(open("pyproject.toml", "rb"))["project"]["version"];
|
|
25
|
+
assert f"v{version}" == os.environ["GITHUB_REF_NAME"]'
|
|
26
|
+
- run: uv build
|
|
27
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Blazing Agents
|
|
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.
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: blazing_agents
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Official Python SDK for Blazing Agents
|
|
5
|
+
Project-URL: Documentation, https://docs.blazingagents.com
|
|
6
|
+
Project-URL: Repository, https://github.com/blazingagents/python-sdk
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Python: >=3.11
|
|
10
|
+
Requires-Dist: httpx<1,>=0.27
|
|
11
|
+
Requires-Dist: pydantic<3,>=2
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
|
|
14
|
+
# Blazing Agents Python SDK
|
|
15
|
+
|
|
16
|
+
The official backend SDK for the Blazing Agents `/v1` API. It provides native
|
|
17
|
+
synchronous and asynchronous clients, typed Pydantic responses, lazy
|
|
18
|
+
pagination, binary transfers, and one-owner generation streams.
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
Blazing Agents supports CPython 3.11 and newer.
|
|
23
|
+
|
|
24
|
+
```console
|
|
25
|
+
pip install blazing_agents
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Create a Tenant API key in the Blazing Agents dashboard. Pass it explicitly or
|
|
29
|
+
set `BLAZING_AGENTS_API_KEY`; an explicit key takes precedence.
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from blazing_agents import BlazingAgents
|
|
33
|
+
|
|
34
|
+
with BlazingAgents(api_key="ba_...") as client:
|
|
35
|
+
tenant = client.tenant.get()
|
|
36
|
+
print(tenant.name)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The production API origin is `https://api.blazingagents.com`. Use `base_url`
|
|
40
|
+
only for an intentional alternative deployment:
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
client = BlazingAgents(
|
|
44
|
+
api_key="ba_...",
|
|
45
|
+
base_url="http://127.0.0.1:8787",
|
|
46
|
+
timeout=30.0,
|
|
47
|
+
on_response=lambda response: print(response.request_id, response.status),
|
|
48
|
+
)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Generation methods accept `client_request_id` for caller-owned correlation
|
|
52
|
+
without raw headers. Use `client.with_options(client_request_id=...)` to
|
|
53
|
+
correlate any resource or generation request through a scoped client view.
|
|
54
|
+
`on_response` receives method, path without query,
|
|
55
|
+
status, duration, server request ID, and the optional client request ID once
|
|
56
|
+
for every received response, including errors and streaming handshakes.
|
|
57
|
+
Callback failures are ignored, and failures with no HTTP response do not
|
|
58
|
+
invoke it. Retain the server-owned `request_id` when contacting support; each
|
|
59
|
+
retry receives a different value.
|
|
60
|
+
|
|
61
|
+
Tenant API-key creation, rotation, and revocation are dashboard-only and are
|
|
62
|
+
not exposed by this backend SDK.
|
|
63
|
+
|
|
64
|
+
## Sync and async clients
|
|
65
|
+
|
|
66
|
+
`BlazingAgents` and `AsyncBlazingAgents` expose the same resources and
|
|
67
|
+
generation behavior. The async client uses HTTPX asynchronously throughout; it
|
|
68
|
+
does not run synchronous calls through an event loop bridge.
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from blazing_agents import AsyncBlazingAgents
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
async def show_tenant() -> None:
|
|
75
|
+
async with AsyncBlazingAgents(api_key="ba_...") as client:
|
|
76
|
+
tenant = await client.tenant.get()
|
|
77
|
+
print(tenant.name)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Context managers close transports created by the SDK. When injecting an
|
|
81
|
+
`httpx.Client` or `httpx.AsyncClient`, the caller retains ownership and must
|
|
82
|
+
close it.
|
|
83
|
+
|
|
84
|
+
## Resources
|
|
85
|
+
|
|
86
|
+
Both clients expose these resource groups:
|
|
87
|
+
|
|
88
|
+
| Resource | Operations |
|
|
89
|
+
| --- | --- |
|
|
90
|
+
| `agents` | Create, list, get, update, disable, enable, delete, versions, restore, MCP attachments, avatar upload/removal |
|
|
91
|
+
| `workspaces` | Create, list, iterate, get, update, delete |
|
|
92
|
+
| `agent(agent_id).skills` | Create/upload, list, iterate, get, delete, read/replace/delete files, copy |
|
|
93
|
+
| `providers` | Create, list, get, update, delete, and discover models |
|
|
94
|
+
| `mcp_connections` | Connect, create, list, get, update, delete, test, reconnect |
|
|
95
|
+
| `prompts` | Create, list, get, update, delete |
|
|
96
|
+
| `memories` | Create, list, iterate, get, update, delete |
|
|
97
|
+
| `sessions` | List, iterate, messages, Tool approvals and continuations, delete |
|
|
98
|
+
| `artifacts` | List, iterate, download URL, buffered/streaming download, delete |
|
|
99
|
+
| `tasks` | Create, list, iterate, get, update, delete, submit, runs, messages, cancel |
|
|
100
|
+
| `usage` | Tenant or Agent usage |
|
|
101
|
+
| `tenant` | Get and update Tenant settings |
|
|
102
|
+
|
|
103
|
+
Writes use keyword-only snake-case parameters. SDK-owned names are translated
|
|
104
|
+
to camel case on the wire; keys inside metadata, message parts, variables, and
|
|
105
|
+
JSON Schema remain unchanged. Omitted values are not sent, while explicit
|
|
106
|
+
`None` is sent as JSON null.
|
|
107
|
+
|
|
108
|
+
Returned objects are strict Pydantic v2 models for documented fields and retain
|
|
109
|
+
unknown server fields in `model_extra`. Successful models expose the
|
|
110
|
+
non-serialized `_request_id` correlation attribute.
|
|
111
|
+
|
|
112
|
+
Every Agent has a Workspace. Omitting `workspace_id` when creating an Agent
|
|
113
|
+
creates its default Workspace; passing an existing ID shares that Workspace.
|
|
114
|
+
Updates accept another concrete Workspace ID, and deleting an Agent preserves
|
|
115
|
+
its Workspace for explicit deletion or reuse.
|
|
116
|
+
|
|
117
|
+
An Agent may be created without a Provider configuration. To configure one,
|
|
118
|
+
pass both `provider_id` and `model`. Updates may replace only the model, replace
|
|
119
|
+
both values, or clear the configuration by passing `None` for both values.
|
|
120
|
+
|
|
121
|
+
## Pagination
|
|
122
|
+
|
|
123
|
+
Cursor resources provide a page-level `list()` and a lazy `iter()`. Iteration
|
|
124
|
+
requests another page only when it is needed.
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
with BlazingAgents(api_key="ba_...") as client:
|
|
128
|
+
page = client.sessions.list(agent_id="ag_...", limit=25)
|
|
129
|
+
print(page.data, page.next_cursor)
|
|
130
|
+
|
|
131
|
+
for session in client.sessions.iter(agent_id="ag_...", limit=25):
|
|
132
|
+
print(session.id)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Async resource iterators are consumed with `async for`:
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
async with AsyncBlazingAgents(api_key="ba_...") as client:
|
|
139
|
+
sessions = client.sessions.iter(agent_id="ag_...", limit=25)
|
|
140
|
+
async for session in sessions:
|
|
141
|
+
print(session.id)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Task pages support the same lazy pagination with `agent_id`, `cursor`, and
|
|
145
|
+
`limit` filters:
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
with BlazingAgents(api_key="ba_...") as client:
|
|
149
|
+
page = client.tasks.list(
|
|
150
|
+
agent_id="ag_...",
|
|
151
|
+
cursor="next-page-token",
|
|
152
|
+
limit=25,
|
|
153
|
+
)
|
|
154
|
+
for task in client.tasks.iter(agent_id="ag_...", limit=25):
|
|
155
|
+
print(task.id)
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Binary transfer
|
|
159
|
+
|
|
160
|
+
Uploads accept `bytes`, a path-like value, or a readable binary file. The SDK
|
|
161
|
+
closes a file it opens from a path and leaves caller-owned file objects open.
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
with BlazingAgents(api_key="ba_...") as client:
|
|
165
|
+
client.agents.upload_avatar("ag_...", file="avatar.png")
|
|
166
|
+
client.agent("ag_...").skills.replace_file(
|
|
167
|
+
skill_id="skill_...",
|
|
168
|
+
path="assets/config.bin",
|
|
169
|
+
content=b"\x00\x01",
|
|
170
|
+
)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Artifact metadata and management are Tenant-level. Create a five-minute
|
|
174
|
+
presigned R2 URL, then fetch the immutable bytes directly:
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
with BlazingAgents(api_key="ba_...") as client:
|
|
178
|
+
artifact = client.artifacts.get(
|
|
179
|
+
artifact_id="at_...",
|
|
180
|
+
)
|
|
181
|
+
download = client.artifacts.create_download_url(
|
|
182
|
+
artifact_id=artifact.artifact_id,
|
|
183
|
+
)
|
|
184
|
+
print(download.url, download.expires_at)
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Use `await async_client.artifacts.create_download_url(...)` with the async
|
|
188
|
+
client. Keep presigned URLs out of logs and referrers.
|
|
189
|
+
|
|
190
|
+
## Chat relay
|
|
191
|
+
|
|
192
|
+
`chat()` returns the server's exact SSE bytes. The SDK does not decode or
|
|
193
|
+
re-encode AI SDK `UIMessageChunk` values, so a backend can relay each byte
|
|
194
|
+
chunk unchanged.
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
with BlazingAgents(api_key="ba_...") as client:
|
|
198
|
+
with client.chat(
|
|
199
|
+
agent_id="ag_...",
|
|
200
|
+
message={"id": "message-1", "role": "user", "parts": []},
|
|
201
|
+
) as stream:
|
|
202
|
+
print(stream.status_code, stream.session_id, stream.request_id)
|
|
203
|
+
for chunk in stream:
|
|
204
|
+
relay(chunk)
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
For a new Session, `session_id` is resolved from the response `Location`
|
|
208
|
+
header. Pass that ID to a later `chat(..., session_id=session_id)` call to
|
|
209
|
+
resume. Status, headers, request ID, and Session ID are available before body
|
|
210
|
+
consumption. `trigger="regenerate-message"` requires an existing `session_id`;
|
|
211
|
+
`message_id` is optional for that regeneration request.
|
|
212
|
+
|
|
213
|
+
## Completion
|
|
214
|
+
|
|
215
|
+
`completion()` buffers plain text. `completion_stream()` yields decoded text
|
|
216
|
+
deltas, and `get_final_text()` drains any unread remainder before returning the
|
|
217
|
+
complete correlated value.
|
|
218
|
+
|
|
219
|
+
```python
|
|
220
|
+
with BlazingAgents(api_key="ba_...") as client:
|
|
221
|
+
result = client.completion(agent_id="ag_...", prompt="Summarize this")
|
|
222
|
+
print(str(result), result.request_id)
|
|
223
|
+
|
|
224
|
+
with client.completion_stream(
|
|
225
|
+
agent_id="ag_...",
|
|
226
|
+
prompt="Write a release note",
|
|
227
|
+
) as stream:
|
|
228
|
+
for delta in stream:
|
|
229
|
+
print(delta, end="")
|
|
230
|
+
final = stream.get_final_text()
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Structured objects
|
|
234
|
+
|
|
235
|
+
Pass either a Pydantic-compatible `output_type` or a raw `json_schema`, but not
|
|
236
|
+
both. A typed result is inferred from `output_type`.
|
|
237
|
+
|
|
238
|
+
```python
|
|
239
|
+
from pydantic import BaseModel
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
class Summary(BaseModel):
|
|
243
|
+
title: str
|
|
244
|
+
risks: list[str]
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
with BlazingAgents(api_key="ba_...") as client:
|
|
248
|
+
summary = client.object(
|
|
249
|
+
agent_id="ag_...",
|
|
250
|
+
prompt="Summarize the release",
|
|
251
|
+
output_type=Summary,
|
|
252
|
+
)
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
`object_stream()` yields raw JSON text deltas. It does not construct partial
|
|
256
|
+
models. `get_final_object()` drains the remainder and validates only after
|
|
257
|
+
successful terminal completion:
|
|
258
|
+
|
|
259
|
+
```python
|
|
260
|
+
with BlazingAgents(api_key="ba_...") as client:
|
|
261
|
+
with client.object_stream(
|
|
262
|
+
agent_id="ag_...",
|
|
263
|
+
prompt="Summarize the release",
|
|
264
|
+
output_type=Summary,
|
|
265
|
+
) as stream:
|
|
266
|
+
for json_delta in stream:
|
|
267
|
+
print(json_delta, end="")
|
|
268
|
+
summary = stream.get_final_object()
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Errors, timeouts, and retries
|
|
272
|
+
|
|
273
|
+
```python
|
|
274
|
+
from blazing_agents import (
|
|
275
|
+
APIConnectionError,
|
|
276
|
+
APIStatusError,
|
|
277
|
+
APITimeoutError,
|
|
278
|
+
StreamError,
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
with BlazingAgents(api_key="ba_...") as client:
|
|
282
|
+
try:
|
|
283
|
+
client.agents.get("ag_...")
|
|
284
|
+
except APIStatusError as error:
|
|
285
|
+
print(error.status_code, error.code, error.request_id, error.retry_after)
|
|
286
|
+
except APITimeoutError:
|
|
287
|
+
...
|
|
288
|
+
except APIConnectionError:
|
|
289
|
+
...
|
|
290
|
+
except StreamError:
|
|
291
|
+
...
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
`APIStatusError` retains response headers, the server error code, details,
|
|
295
|
+
parameter, request ID, retry information, and the safe response body.
|
|
296
|
+
Cancellation, `KeyboardInterrupt`, and `SystemExit` are not wrapped.
|
|
297
|
+
|
|
298
|
+
Ordinary operations default to 60 seconds. Set `timeout` on a client or an
|
|
299
|
+
individual operation; use `None` to disable it. Streaming responses retain
|
|
300
|
+
connect, write, and pool timeouts but deliberately have no SDK read deadline.
|
|
301
|
+
The SDK performs no automatic retries or implicit idempotency. Task submission
|
|
302
|
+
accepts an explicit `idempotency_key` because that operation defines one.
|
|
303
|
+
|
|
304
|
+
## Stream and security ownership
|
|
305
|
+
|
|
306
|
+
Every binary, chat, completion, and object stream has one consumer. Exhaustion
|
|
307
|
+
closes it automatically. Early exit requires `close()` or `aclose()`, normally
|
|
308
|
+
through a context manager. Closing an active chat or generation stream
|
|
309
|
+
propagates cancellation; closing an admitted durable Tool continuation only
|
|
310
|
+
detaches.
|
|
311
|
+
|
|
312
|
+
The SDK is silent by default, sends no telemetry or background analytics, and
|
|
313
|
+
starts no background tasks. If the host enables the `blazing_agents` logger at
|
|
314
|
+
debug level, records contain only HTTP method, path without query parameters,
|
|
315
|
+
status, elapsed time, and request ID. Credentials, headers, query values,
|
|
316
|
+
bodies, schemas, file data, and stream content are never logged.
|
|
317
|
+
|
|
318
|
+
## Verification commands
|
|
319
|
+
|
|
320
|
+
The package checks are self-contained and do not require Supabase:
|
|
321
|
+
|
|
322
|
+
```console
|
|
323
|
+
uv sync --locked
|
|
324
|
+
uv run ruff check .
|
|
325
|
+
uv run ruff format --check .
|
|
326
|
+
uv run python scripts/run_typechecks.py
|
|
327
|
+
uv run python scripts/run_tests.py
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
These commands build and test the installed wheel, enforce the 99% line, branch,
|
|
331
|
+
function, and statement thresholds, runs Pyright and mypy, and checks Ruff.
|
|
332
|
+
Interpreter compatibility uses the same installed-wheel behavioral suite for
|
|
333
|
+
each supported Python version:
|
|
334
|
+
|
|
335
|
+
```console
|
|
336
|
+
uv run --python 3.11 python scripts/run_compatibility.py
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
Repeat the compatibility command with Python 3.12, 3.13, and 3.14. The
|
|
340
|
+
platform integration suite remains in the private platform repository.
|