Commit Graph

10 Commits

Author SHA1 Message Date
Mobiletic
dcb0a3a448 docs: add examples/ (live demo + RESULTS) and slim the README examples
- examples/demo.mjs: live demo (5 single messages up to 5 people with rare
  auto-coined attributes + 5 escalating multi-turn conversations with
  long-range back-references); self-references the package via exports
- examples/RESULTS.md: its generated output (10 examples)
- examples/.env.example + examples/README.md; `npm run example` script
- README: replace the long examples section with two representative examples
  (dense 5-person message + 6-turn conversation) and a badge/link to
  examples/RESULTS.md for the full set
- eslint ignores examples/**, prettier ignores generated examples/RESULTS.md,
  .gitignore un-ignores .env.example

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 15:22:00 +01:00
Mobiletic
d119c366b7 test: add 5 multi-turn conversation examples
Scripted, deterministic conversations (fictional Swiss e-learning chats) via a
mock provider, each asserting exact per-turn round-trips + stable entity ids:
login support (attributes attach to PER_1), two learners (applyKnown reuse of a
re-mentioned name), old/new IBAN kept distinct, parent+minor+doctor (3 people),
and HR (manager+org reused, two employees). 46 tests total.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 14:36:36 +01:00
Mobiletic
5ed8001101 feat: multi-turn conversation support (0.4.0)
anonymizeTurn(text, session) threads a serializable AnonymizerSession
({mapping, legend, history}) so one entity keeps one id across a whole chat
(applyKnown reuse + usedIds + de-collision merge). Adds conversation()
in-memory wrapper and an optional LlmProvider.anonymizeInConversation(text, ctx)
for rich cross-turn context; providers without it fall back to the batch path.

openAICompatibleProvider gains includeMappingInContext (default false — only
send real values to a trusted anonymizer endpoint) + historyMaxTurns (default
10). Verified live vs Gemma 4: Nora stays PER_1 across 4 turns (name/email/AVS/
IBAN), Yanis = PER_2; 41 tests, 98% coverage.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 14:26:41 +01:00
Mobiletic
bc34d9470e docs: add live Gemma-4 e-learning examples to README
Summary table of 5 escalating cases + two inline worked examples (baseline
signup, HR multi-person coreference) + collapsible details (login username
coinage, two-IBAN distinction, minor+health dense coreference). Real
(fictional-data) output, all 5/5 round-trips.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 11:03:00 +01:00
Mobiletic
2584bd8c95 feat: prompt rules for lossless round-trips (0.3.1)
Two coherence rules added to DEFAULT_SYSTEM_PROMPT:
- different values of the same type get distinct placeholders (context),
  e.g. old/new IBAN -> [PER_1.IBAN:Ancien] / [PER_1.IBAN:Nouveau]
- never absorb adjacent punctuation/separators into a placeholder

Took the live Gemma-4 (Infomaniak) e-learning demo from 4/5 to 5/5 exact
round-trips. 36 tests passing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 09:58:56 +01:00
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
Mobiletic
669794522e feat!: optional fail-closed fallback, legend output, richer prompt & docs
BREAKING CHANGE: 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/patterns is
required. AnonymizationResult gains a required `legend`; anonymizeChunks seed
is now { mapping, legend? } and returns legend.

- prompt: model may coin new UPPERCASE abbreviations and returns a 'legende'
  explaining every abbreviation used (French); backfilled by DEFAULT_LEGEND
- PatternDef.meaning surfaces in the legend; swiss/generic presets get meanings
- AnonymizationError (exported) wraps the cause on fail-closed
- README: drop the chatbot provenance line; add 'How it works' + nLPD sections
- 34 tests / 99% coverage; bump to 0.2.0

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 15:28:04 +01:00
Mobiletic
08f84ae14a chore: point repo/badge URLs at git.mobiletic.net Gitea
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 17:09:07 +01:00
Mobiletic
81b6b03239 feat: harden generic preset, add LLM retry, and finish tooling/docs
- PatternDef.validate + Luhn-gated credit-card detection; de-overlap the
  generic phone/date/IP patterns; presets.swiss unchanged (production behavior)
- strip g/y flags from nameHint so .test() is stateless (latent footgun)
- openAICompatibleProvider: bounded retry on transient failures (network /
  timeout / 429 / 5xx), configurable via retries + retryDelayMs
- eslint + prettier + vitest coverage (97%); CI runs lint/format/coverage
- docs: README badges + new-option docs, SECURITY.md, issue/PR templates

26 tests passing; build emits ESM+CJS+types.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 17:03:20 +01:00
Mobiletic
f09b917f1a feat: initial release of @mobiletic/anonymizer
Framework-agnostic PII anonymization extracted from Mobiletic's chatbot.
Pluggable LLM detection + configurable regex fallback, deterministic
coreference, and streaming-safe de-anonymization.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 21:58:38 +01:00