Files
anonymizer/CHANGELOG.md
Mobiletic f5c9f0fbd4 feat: make openAICompatibleProvider work with Infomaniak out of the box (0.3.0)
- response_format is omitted by default (Infomaniak rejects the legacy
  json_object → HTTP 422); opt in via the new `responseFormat` option
  ({type:'json_object'} or a json_schema object). BREAKING for endpoints
  that relied on the forced json_object.
- parse LLM JSON leniently (tolerate markdown fences / surrounding prose)
- fold strict-coherence rules into DEFAULT_SYSTEM_PROMPT (exact
  placeholder<->mapping-key identity, values are originals, strict format,
  mask value not adjacent label) → reliable output across models

Verified live against Gemma 4 (google/gemma-4-31B-it, Infomaniak v2): all
demo phrases anonymize with clean round-trips, no custom provider needed.
36 tests passing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 09:43:19 +01:00

3.6 KiB

Changelog

All notable changes to this project are documented here. The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[0.3.0] - Unreleased

Changed

  • openAICompatibleProvider now works with Infomaniak (and other open-model endpoints) out of the box. response_format is omitted by default instead of hard-coding { type: 'json_object' }, which current Infomaniak rejects (HTTP 422). Pass the new responseFormat option (e.g. { type: 'json_object' } or a json_schema object) for endpoints that support/require it. Breaking for endpoints that relied on the previous forced json_object.
  • JSON responses are now parsed leniently — a fenced JSON code block or surrounding prose is tolerated (the outermost { … } is extracted), so models without an enforced response_format don't cause spurious parse failures.
  • The default prompt gained a COHÉRENCE block (exact placeholder↔mapping-key identity, values are the original data never another placeholder, strict [TYPE_N…] format, mask the value not the adjacent label) to improve reliability across models.

[0.2.0] - Unreleased

Added

  • legend on every result — abbreviation → French meaning (PERPersonne, MMasculin), safe to forward to a downstream LLM so it understands the placeholder tokens. Backed by a built-in DEFAULT_LEGEND so coverage is guaranteed even if the model omits entries.
  • The default prompt now lets the model coin new uppercase abbreviations for entities/attributes/ context it discovers and return their meanings in legende.
  • PatternDef.meaning — optional human label for a tag, surfaced in the legend. presets.swiss/ presets.generic ship French meanings.
  • AnonymizationError (exported) — thrown when anonymization can't complete and no fallback exists; carries the originating error in .cause.

Changed (breaking)

  • Regex fallback is now opt-in. patterns no longer defaults to presets.swiss. With no fallback, an LLM failure throws AnonymizationError (fail-closed) and the pre-filter is bypassed. At least one of llm or patterns is required, or the constructor throws.
  • AnonymizationResult gained a required legend field; LlmProvider.anonymizeBatch returns legend.
  • anonymizeChunks(chunks, seed)seed is now { mapping, legend? } (was the bare mapping) and the return includes legend.

[0.1.0] - Unreleased

Added

  • Initial public release.
  • Anonymizer — pre-filter → LLM → regex fallback, bidirectional validation, deterministic coreference, and de-collision across question and retrieved chunks (anonymize, anonymizeChunks, deanonymize).
  • makeStreamDeanonymizer — streaming-safe de-anonymization that never leaks a split placeholder.
  • openAICompatibleProvider — pluggable LLM detection over any OpenAI-compatible Chat Completions API.
  • presets.swiss and presets.generic regex pattern sets; fully configurable custom patterns.
  • Regex-only mode (no LLM provider required).
  • PatternDef.validate — optional second-stage predicate to cut false positives; presets.generic uses it for a Luhn check on credit-card candidates, and de-overlaps its phone/date/IP patterns.
  • openAICompatibleProvider retries transient failures (network/timeout/429/5xx) via retries and retryDelayMs options; non-transient 4xx and malformed responses are not retried.
  • Hardened the nameHint heuristic: g/y flags are stripped internally so .test() is stateless.