Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
113 commits
Select commit Hold shift + click to select a range
0e3404a
Merge pull request #58 from wild-edge/release/0.2.2
piotrekno1 Sep 30, 2026
4ab5ced
Track llama-cpp chat and completion calls in the gguf integration
piotrekno1 Oct 19, 2026
1e8e19c
README: PyPI badge, links to the app, docs and blog, and where the DS…
piotrekno1 Oct 19, 2026
53a5ff1
Merge pull request #60 from wild-edge/docs/readme-dsn-links
piotrekno1 Oct 19, 2026
63ba169
Update compatibility pins to current releases and test anthropic
piotrekno1 Oct 19, 2026
04319c7
Record chat context, generation config and stop reason for gguf calls
piotrekno1 Oct 20, 2026
f48992b
Cover the gguf integration's fallback and error paths
piotrekno1 Oct 20, 2026
2f07377
Make compat tests run each integration and fail instead of skipping
piotrekno1 Oct 20, 2026
7fb9cc2
Generate the compat CI matrix from compat_matrix.py and run it on dev…
piotrekno1 Oct 20, 2026
14a7ce2
Pin setuptools for ultralytics 8.0.0 on Python 3.12 and 3.13
piotrekno1 Oct 20, 2026
0270e0c
Run compat on pull requests into main and release branches only
piotrekno1 Oct 20, 2026
7bba65c
Download the GGUF test model instead of committing it
piotrekno1 Oct 20, 2026
d74d1d3
Docs: the gguf compat model is downloaded
piotrekno1 Oct 20, 2026
24a2202
Merge pull request #69 from wild-edge/ci/compat-current-pins
piotrekno1 Oct 20, 2026
97bd484
Merge remote-tracking branch 'origin/devel' into fix/gguf-track-creat…
piotrekno1 Oct 20, 2026
4c22567
Check gguf chat and completion tracking against real llama-cpp-python
piotrekno1 Oct 20, 2026
b88d048
Make the gguf example a multi-turn chat
piotrekno1 Oct 20, 2026
aea50b1
Import inspect at module level in the gguf tests
piotrekno1 Oct 20, 2026
156ad6d
Enable more ruff rules and check lint in CI
piotrekno1 Oct 20, 2026
6164983
Fix lint findings in the SDK and examples
piotrekno1 Oct 20, 2026
44ed3b7
Fix lint findings in the tests
piotrekno1 Oct 20, 2026
3992cdf
Merge pull request #59 from wild-edge/fix/gguf-track-create-completion
piotrekno1 Oct 20, 2026
3eebea3
Send non-scalar span attributes as JSON strings
piotrekno1 Oct 20, 2026
0b89bb6
Cover the str() fallback for span attributes JSON can't encode
piotrekno1 Oct 20, 2026
b97136a
Import the events common module at module level in the tests
piotrekno1 Oct 20, 2026
9b15261
Merge pull request #66 from wild-edge/fix/span-attribute-scalars
piotrekno1 Oct 20, 2026
6dadbea
Upload buffered attachments on close and flush with a timeout
piotrekno1 Oct 20, 2026
50fab2b
Import constants and WildEdge at module level in the new attachment t…
piotrekno1 Oct 20, 2026
5fb8f30
Merge pull request #67 from wild-edge/fix/close-uploads-attachments
piotrekno1 Oct 20, 2026
c46afdf
Name ONNX models after their file when the graph name is generic
piotrekno1 Oct 20, 2026
9725f2c
Use a fake clock in the attachment deadline tests
piotrekno1 Oct 20, 2026
d61591c
Merge pull request #68 from wild-edge/fix/onnx-generic-graph-names
piotrekno1 Oct 20, 2026
f267a6d
Merge pull request #76 from wild-edge/fix/flaky-attachment-deadline-t…
piotrekno1 Oct 20, 2026
e7e45ad
Merge remote-tracking branch 'origin/devel' into chore/ruff-lint-rules
piotrekno1 Oct 20, 2026
f5872e0
Fix lint findings from the PRs merged since
piotrekno1 Oct 20, 2026
363d714
Track each transformers pipeline call once
piotrekno1 Oct 20, 2026
900bd87
Merge pull request #75 from wild-edge/chore/ruff-lint-rules
piotrekno1 Oct 20, 2026
6229004
Keep pipeline tracking state in a typed thread-local
piotrekno1 Oct 20, 2026
cd5c34d
Merge remote-tracking branch 'origin/devel' into fix/transformers-pip…
piotrekno1 Oct 20, 2026
2fd5324
Only suppress the pipeline's own model during a pipeline call
piotrekno1 Oct 20, 2026
17f4336
Merge pull request #77 from wild-edge/fix/transformers-pipeline-doubl…
piotrekno1 Oct 20, 2026
77c52ea
Require ultralytics 8.0.200 and warn on older releases
piotrekno1 Oct 20, 2026
4471b15
Merge pull request #79 from wild-edge/fix/ultralytics-min-version
piotrekno1 Oct 20, 2026
7a16e63
Add OpenAI Responses API instrumentation
piotrekno1 Oct 20, 2026
0ede5c6
Merge pull request #80 from wild-edge/feat/openai-responses
piotrekno1 Oct 20, 2026
9577047
Add OpenAI embeddings instrumentation
piotrekno1 Oct 20, 2026
13c2d2b
Merge pull request #81 from wild-edge/feat/openai-embeddings
piotrekno1 Oct 20, 2026
b0982aa
Track streaming lifecycle outcomes exactly once
piotrekno1 Oct 20, 2026
1b0192f
Classify truncated remote streams as incomplete
piotrekno1 Oct 20, 2026
b548b46
Handle Anthropic stream event names across supported SDKs
piotrekno1 Oct 20, 2026
bf04c46
Instrument Anthropic native streaming helpers
piotrekno1 Oct 20, 2026
672502b
Merge pull request #82 from wild-edge/fix/streaming-lifecycle
piotrekno1 Oct 20, 2026
66a0fb5
Merge pull request #83 from wild-edge/feat/anthropic-native-stream
piotrekno1 Oct 20, 2026
98e6a7c
Track Ultralytics predict through the common entry point
piotrekno1 Oct 20, 2026
05691eb
Merge pull request #84 from wild-edge/fix/ultralytics-predict
piotrekno1 Oct 20, 2026
e410648
Preserve timm architecture names in model identity
piotrekno1 Oct 20, 2026
dfb7b13
Merge pull request #86 from wild-edge/fix/timm-model-identity
piotrekno1 Oct 20, 2026
c5b8d0f
Support sequential auto-instrumentation client replacement
piotrekno1 Oct 20, 2026
665f898
Merge pull request #87 from wild-edge/fix/instrumentation-client-repl…
piotrekno1 Oct 20, 2026
db42ed6
Add local Whisper transcription instrumentation
piotrekno1 Oct 20, 2026
642b619
Polish Whisper instrumentation from review
piotrekno1 Oct 21, 2026
00dd90e
Name Whisper magic values and tidy shared helpers
piotrekno1 Oct 21, 2026
68998df
Report Whisper accelerators with the SDK's names
piotrekno1 Oct 21, 2026
87dc335
Use shared accelerator names across the SDK
piotrekno1 Oct 21, 2026
d20e737
Use shared quantization labels across the SDK
piotrekno1 Oct 21, 2026
aba75f0
Merge pull request #88 from wild-edge/feat/whisper-instrumentation
piotrekno1 Oct 21, 2026
81e42de
Merge pull request #90 from wild-edge/fix/accelerator-constants
piotrekno1 Oct 21, 2026
b1bd7e0
Merge pull request #91 from wild-edge/fix/quantization-names
piotrekno1 Oct 21, 2026
9098d9b
Name adapters and hub trackers by import path in the registries
piotrekno1 Oct 21, 2026
b1b299e
Load adapters and hub trackers only when they are used
piotrekno1 Oct 21, 2026
463ba85
Import framework runtimes when their integration is activated
piotrekno1 Oct 21, 2026
cb9b5ca
Test and document that SDK import loads no ML libraries
piotrekno1 Oct 21, 2026
fca35a1
Merge pull request #89 from wild-edge/fix/lazy-integration-imports
piotrekno1 Oct 21, 2026
24c6887
Let apps choose which kinds of data attachments may upload
piotrekno1 Oct 21, 2026
f66f3b4
Warn when attachment modalities are set but attachments are off
piotrekno1 Oct 21, 2026
998a6ed
Add a Modality enum and accept it wherever modalities are named
piotrekno1 Oct 21, 2026
ff64a7c
Show Modality constants in every Python example
piotrekno1 Oct 21, 2026
193f51e
Require explicit attachments across Python integrations
piotrekno1 Oct 21, 2026
7075312
Merge pull request #92 from wild-edge/feat/attachment-modalities
piotrekno1 Oct 21, 2026
35e5dcf
Let a new registration replace persisted model metadata (#56)
piotrekno1 Oct 21, 2026
4384de0
Name llama.cpp integration after its runtime and simplify README (#93)
piotrekno1 Oct 21, 2026
18386c2
Give README a complete local inference quickstart
piotrekno1 Oct 21, 2026
9b765d2
Keep traced local and remote workflow as expandable example
piotrekno1 Oct 21, 2026
3e5e2a9
Add clickable demo performance preview to README
piotrekno1 Oct 21, 2026
67393b0
Capture demo at desktop size without sidebar overflow
piotrekno1 Oct 21, 2026
4acdc53
Limit README demo preview to 640 pixels wide
piotrekno1 Oct 21, 2026
7f6a00d
Use three small expandable README screenshot thumbnails
piotrekno1 Oct 21, 2026
9448483
Remove release documentation bundle note from README
piotrekno1 Oct 21, 2026
68c8ff6
Clarify README setup, integration activation and telemetry
piotrekno1 Oct 21, 2026
c69008b
Make integration overview compact with expandable reference
piotrekno1 Oct 21, 2026
3c9667d
Move API-specific README details into provider documentation
piotrekno1 Oct 21, 2026
e9c6038
Merge pull request #94 from wild-edge/docs/readme-local-quickstart
piotrekno1 Oct 21, 2026
68580ce
Show compact trace and SQL previews with extra views collapsed
piotrekno1 Oct 21, 2026
d98df57
Show computed sample SQL results as stacked model volumes
piotrekno1 Oct 21, 2026
ba7b637
Merge pull request #95 from wild-edge/docs/readme-trace-sql-gallery
piotrekno1 Oct 21, 2026
bf806c9
Merge branch 'main' of github.com:wild-edge/wildedge-python into devel
piotrekno1 Oct 21, 2026
d7fc6a6
Fix whisper example span kind and add uv script header
piotrekno1 Oct 21, 2026
faa5f77
Pin httpx 0.27 for the openai min compat rows
piotrekno1 Oct 21, 2026
f1225f5
Merge duplicate changelog groups and list instrumentation ownership a…
piotrekno1 Oct 21, 2026
cb23ef1
Serialize consumer drains so flush() cannot resend an in-flight batch
piotrekno1 Oct 21, 2026
0e24083
Add streaming and whisper docs to llms.txt
piotrekno1 Oct 21, 2026
fd90cd0
Warn instead of raising on instrumentation ownership conflicts
piotrekno1 Oct 21, 2026
d45c19a
Release 0.3.0
piotrekno1 Oct 21, 2026
397a9bd
Merge pull request #96 from wild-edge/release/0.3.0-fixes
piotrekno1 Oct 21, 2026
8adbaca
Scan module dicts when patching Hugging Face download functions
piotrekno1 Oct 21, 2026
90cb8cd
Merge pull request #97 from wild-edge/fix/hf-hub-patch-lazy-imports
piotrekno1 Oct 21, 2026
6c3a54e
Move the Hugging Face hub fix into the 0.3.0 changelog
piotrekno1 Oct 21, 2026
1c14a3c
Cap error_message and provider_error_code for manual track_error calls
piotrekno1 Oct 22, 2026
451ef86
Keep the start and end of long error messages, up to 500 characters
piotrekno1 Oct 22, 2026
db8d859
Build release notes from the version's CHANGELOG.md section
piotrekno1 Oct 22, 2026
b98d2b0
Merge pull request #99 from wild-edge/fix/truncate-error-fields
piotrekno1 Oct 22, 2026
e8e70f9
Correct the 0.3.0 attachments changelog entry
piotrekno1 Oct 24, 2026
61fb799
Date the 0.3.0 release 2026-10-24
piotrekno1 Oct 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ on:
- 'wildedge/**'
- 'tests/**'
- 'scripts/**'
- 'examples/**'
- 'pyproject.toml'
- 'uv.lock'
- '.github/workflows/ci.yml'
Expand All @@ -16,11 +17,31 @@ on:
- 'wildedge/**'
- 'tests/**'
- 'scripts/**'
- 'examples/**'
- 'pyproject.toml'
- 'uv.lock'
- '.github/workflows/ci.yml'

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install uv
run: |
pip install uv
- name: Install dependencies
run: |
uv sync --group dev
- name: Ruff lint
run: uv run ruff check --output-format=github .
- name: Ruff format
run: uv run ruff format --check .

test:
runs-on: ${{ matrix.os }}
strategy:
Expand Down
99 changes: 33 additions & 66 deletions .github/workflows/compat.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
name: Compatibility

# Runs tests/compat against the pinned library versions in
# scripts/compat_matrix.py, which is also the source of the job matrix and of
# docs/compatibility.md.
#
# Every run uses the full matrix. It runs on pull requests into main or a
# release branch, on pushes to them, nightly against devel, and on demand.

on:
push:
branches: [ main, 'release/**' ]
Expand All @@ -10,7 +17,7 @@ on:
- 'pyproject.toml'
- '.github/workflows/compat.yml'
pull_request:
branches: [ main ]
branches: [ main, 'release/**' ]
types: [opened, synchronize, reopened]
paths:
- 'wildedge/**'
Expand All @@ -23,46 +30,23 @@ on:
workflow_dispatch:

jobs:
compat:
if: github.event_name != 'pull_request' || startsWith(github.head_ref, 'release/')
matrix:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
integration: ["onnx", "torch", "timm", "tensorflow", "gguf", "openai", "transformers", "ultralytics"]
version-set: ["min", "current"]
exclude:
- python-version: "3.13"
integration: "tensorflow"
outputs:
rows: ${{ steps.rows.outputs.rows }}
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install project
run: |
python -m pip install --upgrade pip
pip install -e . pytest pytest-asyncio pytest-mock
- name: Install compatibility dependencies
run: |
python scripts/compat_matrix.py deps \
--integration "${{ matrix.integration }}" \
--version-set "${{ matrix.version-set }}" \
--python-version "${{ matrix.python-version }}" > compat-requirements.txt
pip install -r compat-requirements.txt
- name: Run compatibility test
run: python -m pytest "tests/compat/test_${{ matrix.integration }}_compat.py" -q
- id: rows
run: echo "rows=$(python scripts/compat_matrix.py github-matrix)" >> "$GITHUB_OUTPUT"

compat-mlx:
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
runs-on: macos-14
compat:
needs: matrix
name: compat (${{ matrix.python-version }}, ${{ matrix.integration }}, ${{ matrix.version-set }})
runs-on: ${{ matrix.runs-on }}
continue-on-error: ${{ matrix.canary }}
strategy:
fail-fast: false
matrix:
python-version: ["3.12", "3.13"]
version-set: ["current"]
matrix: ${{ fromJSON(needs.matrix.outputs.rows) }}
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
Expand All @@ -76,40 +60,23 @@ jobs:
- name: Install compatibility dependencies
run: |
python scripts/compat_matrix.py deps \
--integration "mlx" \
--integration "${{ matrix.integration }}" \
--version-set "${{ matrix.version-set }}" \
--python-version "${{ matrix.python-version }}" > compat-requirements.txt
pip install -r compat-requirements.txt
- name: Run compatibility test
run: python -m pytest tests/compat/test_mlx_compat.py -q

compat-canary-314:
if: github.event_name != 'pull_request' || startsWith(github.head_ref, 'release/')
runs-on: ubuntu-latest
continue-on-error: true
strategy:
fail-fast: false
matrix:
integration: ["torch", "timm", "tensorflow"]
version-set: ["current"]
exclude:
- integration: "tensorflow"
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.14
uses: actions/setup-python@v5
with:
python-version: "3.14"
- name: Install project
- name: Check installed versions match the pins
run: |
python -m pip install --upgrade pip
pip install -e . pytest pytest-asyncio pytest-mock
- name: Install compatibility dependencies
run: |
python scripts/compat_matrix.py deps \
python scripts/compat_matrix.py verify \
--integration "${{ matrix.integration }}" \
--version-set "${{ matrix.version-set }}" \
--python-version "3.14" > compat-requirements.txt
pip install -r compat-requirements.txt
- name: Run compatibility test
run: python -m pytest "tests/compat/test_${{ matrix.integration }}_compat.py" -q
--python-version "${{ matrix.python-version }}"
- name: Cache downloaded test models
if: matrix.integration == 'llama_cpp' || matrix.integration == 'faster_whisper'
uses: actions/cache@v4
with:
path: |
tests/compat/.cache
~/.cache/huggingface/hub
key: compat-models-${{ matrix.integration }}-${{ hashFiles(format('tests/compat/test_{0}_compat.py', matrix.integration)) }}
- name: Run compatibility tests
run: python -m pytest "tests/compat/test_${{ matrix.integration }}_compat.py" -q -rxX
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -218,3 +218,6 @@ internal/

# macOS
.DS_Store

# Models downloaded by the compat tests
tests/compat/.cache/
140 changes: 138 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,144 @@ under Unreleased and move into a version section at release time.

## Unreleased

## 0.3.0 - 2026-10-24

### Added

- `mlx_whisper` and `faster_whisper` integrations track local Whisper model
loads and transcriptions, including faster-whisper's
`BatchedInferencePipeline`. Transcriptions record duration, language, word
count and audio metadata. Audio and transcript attachments must be supplied
explicitly through the manual tracking API. See docs/whisper.md.
- The OpenAI integration now tracks `responses.create()` for synchronous and
asynchronous clients, including streaming. Records input/output token usage,
cached and reasoning tokens, response status or incomplete reason, resolved
model metadata, and time to first output delta for streams. Older OpenAI SDKs
without Responses remain supported.
- OpenAI sync and async `embeddings.create()` instrumentation records latency,
input token usage, batch size, vector dimensions, model metadata and errors.
Embedding vectors and raw inputs are never attached by this adapter.
`EmbeddingOutputMeta` now accepts optional `tokens_in` for analytics.
- Anthropic native `messages.stream()` helpers are now instrumented for sync
and async clients, including event iteration, `text_stream`, and final-message
helpers, with the shared streaming lifecycle contract.
- Process-wide integrations and hub patches now support sequential SDK client
replacement after the previous owner closes. Reinitialization replaces a
closed default. Existing models and provider clients keep their original
destination and must be recreated. Attempts to use a closed telemetry
destination warn once instead of silently dropping inference and error
events.

### Changed

- The llama.cpp Python integration is now named `llama_cpp` in Python, CLI,
and environment configuration. `gguf` remains a compatibility alias; `all`
selects the integration once under its new name. Model format metadata
remains `gguf`.
- `wildedge.init(dsn=...)` reuses the existing default client when the DSN
points to the same project, for example `dsn=os.environ["WILDEDGE_DSN"]`
under `wildedge run`. It used to create a second client.
- Enabling an integration or hub on a second client while another live client
owns process-wide instrumentation now logs a warning. Automatic events keep
going to the owner's project, as before, but this used to happen without a
word. With `wildedge run --strict-integrations` it raises `RuntimeError`.
- Quantization labels are defined once in `wildedge.quantizations` and used
by every integration. Behaviour changes:
- MLX-LM reports N-bit weights as `int4`/`int8`, like Transformers, instead
of `q4`/`q8`.
- GGUF models labelled from `general.file_type` report the type name (for
example `q4_k_m`) instead of its number, and the `i8` filename suffix
reports `int8`.
- faster-whisper reports weight precision (`int8`, `f16`) instead of
CTranslate2 compute types such as `int8_float32`.
- The ultralytics integration now requires ultralytics 8.0.200 or later
(was 8.0.0). Earlier 8.0.x releases keep their helpers under
`ultralytics.yolo.utils`, and the integration turned itself off on them
without a word. `instrument("ultralytics")` now logs a warning naming the
installed version instead.

### Fixed

- Every error event now caps `error_message` at 500 characters, keeping the
start and the end of a longer message. Integrations used to cut it to the
first 200, which lost the cause in messages that end with it, such as
mlx-whisper audio errors that start with the ffmpeg banner. Manual
`track_error()` calls had no limit at all. `provider_error_code` is capped
at 64 characters for every event.
- The llama.cpp integration now tracks `Llama.create_chat_completion()` and
`Llama.create_completion()`, streaming or not. It used to patch only
`Llama.__call__`, so chat apps on llama-cpp-python reported model loads but
no inference events. It now patches `create_completion`, which every entry
point runs, so each call is tracked once.
- llama.cpp inference events now include the stop reason for non-streamed
calls, the generation config (`temperature`, `top_p`, `top_k`, `max_tokens`,
`repeat_penalty`, penalties, `seed`, stop sequence count), and, for chat
calls, `prompt_type="chat"` and `turn_index` measured on the last user
message. Prompts, chat messages and replies are never attached. As before,
attachments upload only when passed to `track_inference(attachments=[...])`.
- `import wildedge` no longer imports every installed ML framework and API
client. Each library is imported when its integration is activated or a
model from it is registered, so SDK import is faster and a broken unrelated
package no longer stops the SDK from starting.
- Changing a model's metadata (for example `register_model(..., version="v2")`)
now takes effect after a restart. With offline persistence on (the default),
the model registry saved by an earlier process kept the first metadata ever
registered for each model on that machine, so later changes were ignored.
This includes anthropic models already saved as `"unknown"`.
- MLX-LM models now report the device they run on (`mps` for the Apple GPU)
instead of always `cpu`. Accelerator names are defined once in
`wildedge.accelerators`, and PyTorch, Transformers, Ultralytics,
TensorFlow and Keras share their device detection.
- timm models now use the requested architecture/variant name for model identity
instead of the Python class name, so models such as resnet18 and resnet50 no
longer share telemetry. Manual registration falls back to timm architecture
metadata, and explicit model IDs retain priority.
- Ultralytics `model.predict()` now records inference telemetry. Instrumentation
patches `predict`, which `model(...)` delegates to, so both entry points are
tracked exactly once.
- Streaming wrappers now finalize once across exhaustion, explicit closure,
cancellation, and iterator errors. Early closure/cancellation records an
unsuccessful inference with partial metadata when available. TTFT ignores
lifecycle/role-only chunks; telemetry callbacks cannot break iteration and
retain the trace context captured at stream creation. Remote API streams
ending without their completion marker record `STREAM_INCOMPLETE`.
- A span attribute whose value is a list, dict or other non-scalar no longer
gets the whole event batch rejected. Ingest only accepts scalar attribute
values and answered 422 for the batch, dropping unrelated loads, inferences
and spans. Such values are now sent as JSON strings, with one warning per
key.
- `close(timeout=...)` and `flush(timeout=...)` now upload buffered
attachments in the time left after sending events. `close()` used to stop
the attachment uploader without a final upload, so a short-lived process
lost the attachments of its last few seconds (the uploader runs every 5 s)
while its events still referenced them. `close()` without a timeout still
leaves them on disk for the next start.
- ONNX models exported with the default `main_graph` graph name (newer
`torch.onnx.export`, Piper TTS voices) are now named after their file, so
different voices no longer show up as one model called `main_graph`. A
session created without an `id` falls back to the file name too, and
`model_version` 0, negative or INT64_MAX (the exporters' "unset") is sent as
`unknown` instead of `9223372036854775807`.
- transformers pipelines called with a string or a list record one inference
event per call instead of two. `pipeline()` loads the model before
`Pipeline.__init__` runs, so the model was registered with its own forward
hooks, and each pipeline call was tracked by the pipeline and again by the
model inside it. That model's hooks now skip forward passes inside a
tracked call of its pipeline; other models the pipeline runs, and direct
calls to the model, are still tracked. Generator and dataset inputs, which
run lazily, are not covered yet (#78).
- `flush()` no longer sends a batch the background sender is already sending.
Both used to send the same events and then each removed a batch from the
queue, so events were duplicated and, depending on timing, later events
could be removed without being sent. This showed up when a process started
with events saved by an earlier run and flushed soon after.
- Enabling the `huggingface` hub no longer imports unused transformers model
modules. To find references to `hf_hub_download` and `snapshot_download`,
the hub tracker looked up the name on every loaded module, and transformers'
lazy modules import code on lookup. With transformers loaded this imported
about 140 extra modules, took about 0.15 s and logged about 430 "failed to
patch" debug lines. The tracker now reads each module's namespace instead.

## 0.2.2 - 2026-09-30

### Added
Expand Down Expand Up @@ -38,8 +176,6 @@ under Unreleased and move into a version section at release time.
- Models tracked by the anthropic integration register with `model_format`
`"api"`, like the openai integration. The Anthropic extractor was never in
the client's extractor list, so they were registered as `"unknown"`.
Machines that already tracked these models keep the saved `"unknown"` until
the SDK's model registry file is deleted.

## 0.2.1 - 2026-09-01

Expand Down
5 changes: 4 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
uv run ruff check .
uv run ruff format .
```
CI runs both (`ruff check` and `ruff format --check`) and fails on any finding.
The rule set is in `pyproject.toml`; prefer fixing over `# noqa`, and give a
reason when a `noqa` is needed.

- Follow PEP 8 and PEP 484 (type hints).

Expand All @@ -46,7 +49,7 @@
Releases follow a `release/<version>` branching flow:

1. Cut a `release/<version>` branch from `devel`.
2. Bump the version in `pyproject.toml`.
2. Bump the version in `pyproject.toml` and move the Unreleased entries in `CHANGELOG.md` into a `## <version> - <date>` section. The release notes are that section, so the release fails without it.
3. Open a pull request targeting `main`. CI will automatically run the full compatibility matrix and post a changelog preview comment.
4. Once merged, tag the commit as `v<version>`. The release workflow publishes to PyPI and creates a GitHub release.

Expand Down
Loading
Loading