You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGES.txt
+1Lines changed: 1 addition & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -230,3 +230,4 @@ v<3.5.3>, <05/19/2026> -- KB-tools API for agent-driven and LLM-API-driven routi
230
230
v<3.5.4>, <06/03/2026> -- Claims-honesty and framing-consistency remediation of the v3 agentic layer from an internal audit (no detector behavior change). Determinism: `ADEngine.random_state` docstring upgraded from the vague "deterministic-up-to-numpy-module-state" hedge to the audited guarantee (a run-to-run audit of the shipped shallow detectors found every one either honors the seed or is deterministic by construction; deep detectors additionally depend on framework seeding). Counts: every public surface now reports 60 buildable detectors instead of 60+/61/50+; `scripts/regen_skill.py` and `pyod/cli.py` exclude `status == "planned"` so the non-buildable `LLMAD` no longer inflates the od-expert skill's counts/lists or `pyod info` (now `60 total (43 tabular, 7 time-series, 8 graph, 2 text, 2 image, 1 multimodal)`); `LLMAD` stays in the raw KB as a roadmap entry. Expert-level: `docs/index.rst`, `od_expert/SKILL.md`, `docs/skill_maintenance.rst`, and `docs/examples/agentic.rst` reword "expert-level/expert-quality results" to a complete-workflow/accessibility claim. Trust verdict: `docs/examples/adengine.rst` demotes the quality verdict to descriptive diagnostics with a "heuristic, not a guarantee" note and corrects the stale "Jaccard" stability description to the cutoff-gap formula; `_quality_metrics.compute_quality` docstring documents `separation` as circular (computed from the run's own predicted labels, near-always high, and not independent of the majority-vote consensus labels); the od-expert skill's Trigger 4 is reframed to cutoff-instability on `stability` only, and its result-interpretation, per-modality confidence lines, and examples route confidence through low `agreement` plus label-free caveats instead of `separation`/`overall`/`verdict`. Consensus: skill guidance softened from "never report from a single detector" to "prefer consensus for robustness; about as accurate as the best single pick." Framing consistency: ADEngine is described as a "lifecycle orchestration" engine rather than "intelligent orchestration" across README, docs, the API reference, and the module docstring, matching the finding that the layer's value is the drivable, reproducible workflow rather than selection intelligence. Tests: 2 new count-locking regression tests (`test_cli.py::test_pyod_info_excludes_planned_detectors`, `test_skill_kb_consistency.py::test_skill_count_prose_matches_kb`) compute expected buildable counts from the KB and fail on regression. Reviewed via /implement-review (Codex, 4 rounds): R1 raised 3 High + 2 Medium + 1 Low, R2 verified 5/6 and flagged trust-gate residue, R3 cleared it, R4 confirmed commit-ready. No breaking API changes.
231
231
v<3.6.0>, <06/04/2026> -- Add audio as a first-class anomaly detection modality. New AudioFeatureEncoder reduces each clip to a 74-dimensional handcrafted acoustic vector (20 MFCC, 12 chroma, and 5 spectral descriptors: centroid, bandwidth, rolloff, zero-crossing rate, and RMS, each as its mean and standard deviation over frames, via librosa), registered as the 'audio-mfcc' encoder and exposed through EmbeddingOD.for_audio() so any classical detector runs on audio. New AudioAE detector is a DCASE-style log-mel reconstruction autoencoder that reuses the PyOD AutoEncoder with clip-level error aggregation. ADEngine now profiles audio file paths and routes audio, with EmbeddingOD.for_audio as the default and AudioAE as the deep alternative; the knowledge base gains an AudioAE entry and audio support on EmbeddingOD and MultiModalOD. New optional extra pyod[audio] (librosa, soundfile). Buildable detector count rises from 60 to 61. References are the public methods (the DCASE 2020 Task 2 log-mel autoencoder baseline, and MFCC, chroma, and spectral features via librosa). Reviewed via /implement-review (Codex, no High findings; one Medium and two Low fixed). No breaking API changes.
232
232
v<3.6.1>, <06/16/2026> -- Maintenance and contributor PRs since v3.6.0 (no breaking API changes). PyThresh v1 support (#684, Daniel Kulik): the pyod.models.thresholds wrappers and the BaseDetector threshold path use the pythresh v1 API (.fit()/.labels_/.predict() instead of .eval()), and the dependency pin moves to pythresh>=1.0.0. EmbeddingOD air-gapped and pre-instantiated encoder support (#696, Sunny Guntuka): a pre-loaded SentenceTransformer instance can be passed directly as the encoder, and a local filesystem path is loaded with local_files_only=True (no Hub call) for offline use; this also fixes a resolver-order bug where a SentenceTransformer instance was wrapped as a CallableEncoder (calling model(X) instead of model.encode(X)). DataFrame feature-name warning fix (#692, eferhire ugbotu; closes #540): GMM, IForest, LOF, and OCSVM run check_array in decision_function, so scoring a pandas DataFrame after fitting no longer emits the scikit-learn feature-name UserWarning; the predict/predict_proba/predict_confidence paths route through decision_function, so the single-point fix covers them. Audio docs: AudioAE and the audio modality are now in the README and docs algorithm tables with a new pyod.models.audio API page (v3.6.0 shipped AudioAE without a table row). Tests: regression tests for the DataFrame-warning fix (GMM/OCSVM/LOF) and a no-download EmbeddingOD resolver test using SentenceTransformer(modules=[]). Docs: PyPI download figure refreshed to 46M+. Reviewed via /implement-review (Codex gatekeeper): #696 and #692 merged after dual review, with the gatekeeper-flagged test gaps closed in a follow-up. Buildable detector count unchanged at 61.
233
+
v<3.6.2>, <07/20/2026> -- Security hardening for model persistence (CVE-2026-15529): both `pyod.utils.persistence.load()` and `pyod.utils.persistence.compat_load()` now refuse to deserialize pickle/joblib artifacts unless callers pass `trusted=True`, making the trust boundary explicit before `joblib.load()` can execute pickle reducers. This is a breaking change: existing `save()` then `load()` round trips, and any direct `compat_load()` calls, must add `trusted=True`, because both functions now refuse even artifacts you saved yourself until the caller acknowledges the source is trusted. The internal `load()` fall-through to `compat_load()` forwards the acknowledgement automatically, so `load(path, trusted=True)` still recovers legacy dtype-mismatched artifacts in a single call. `strict=True` remains a dependency-version policy and is documented as not making untrusted pickle files safe. Adds regression tests verifying that both the default `load()` path and a direct `compat_load()` call reject before any unpickling side effects occur. Updates the model persistence guide, decision tree, troubleshooting table, and save/load example to pass `trusted=True` for trusted artifacts. Closes #697.
``node array from the pickle has an incompatible dtype`` Try :func:`~pyod.utils.persistence.compat_load`. If it succeeds, re-save with :func:`~pyod.utils.persistence.save`. If it raises, re-fit.
172
+
``node array from the pickle has an incompatible dtype`` Try :func:`~pyod.utils.persistence.compat_load` with ``trusted=True``. If it succeeds, re-save with :func:`~pyod.utils.persistence.save`. If it raises, re-fit.
161
173
``InconsistentVersionWarning`` (only a warning, not an error) Safe to ignore; sklearn is reminding you the save and run versions differ. Re-save or re-fit when convenient.
162
174
Other sklearn unpickling errors The artifact is incompatible beyond what ``compat_load`` repairs. Re-fit on the current sklearn.
0 commit comments