buildPIIStatus builds the pii section of /api/middleware/status. It walks every model config and reports the resolved enabled state plus the NER detector models each one references — that's what the admin page renders so the operator can see at a glance which models are protected and by which detect
(app *application.Application)
| 306 | // (entity→action, min score) lives on each detector model's |
| 307 | // pii_detection block. |
| 308 | func buildPIIStatus(app *application.Application) map[string]any { |
| 309 | appCfg := app.ApplicationConfig() |
| 310 | models := []map[string]any{} |
| 311 | for _, cfg := range app.ModelConfigLoader().GetAllModelsConfigs() { |
| 312 | // Only list models PII filtering can actually apply to (reachable |
| 313 | // through a text-accepting endpoint with a PII adapter wired). |
| 314 | // Skips VAD/STT/embedding/image-only models and the token_classify |
| 315 | // detector models themselves, which are the filters, not consumers. |
| 316 | if !cfg.PIIFilterApplies() { |
| 317 | continue |
| 318 | } |
| 319 | explicit := cfg.PII.Enabled != nil |
| 320 | ownDetectors := cfg.PIIDetectors() |
| 321 | // Resolve through the shared policy so the table reflects the EFFECTIVE |
| 322 | // state, including the instance-wide default detector — what the |
| 323 | // request path actually does. |
| 324 | enabled, detectors := app.ResolvePIIPolicy(&cfg) |
| 325 | |
| 326 | entry := map[string]any{ |
| 327 | "name": cfg.Name, |
| 328 | "backend": cfg.Backend, |
| 329 | "enabled": enabled, |
| 330 | "detectors": detectors, |
| 331 | "explicit": explicit, |
| 332 | // Why is this on? backend default (cloud-proxy) vs an explicit YAML |
| 333 | // toggle. Helps admins understand the resolved state without |
| 334 | // reading source. |
| 335 | "default_for_backend": !explicit && cfg.Backend == "cloud-proxy", |
| 336 | // The detectors came from the global default, not this model's YAML. |
| 337 | "detectors_from_default": enabled && len(ownDetectors) == 0 && len(detectors) > 0, |
| 338 | } |
| 339 | models = append(models, entry) |
| 340 | } |
| 341 | |
| 342 | // Detector models: the token_classify "filter" models themselves (NER and |
| 343 | // in-process pattern matchers), which PIIFilterApplies deliberately omits |
| 344 | // from the consumer list above. The Filtering tab renders these as a table |
| 345 | // with a per-row toggle marking membership in the instance-wide default |
| 346 | // detector set, so admins manage defaults without retyping model names. |
| 347 | defaultSet := map[string]bool{} |
| 348 | for _, d := range appCfg.PIIDefaultDetectors { |
| 349 | defaultSet[d] = true |
| 350 | } |
| 351 | detectorModels := []map[string]any{} |
| 352 | for _, cfg := range app.ModelConfigLoader().GetAllModelsConfigs() { |
| 353 | if !cfg.HasUsecases(config.FLAG_TOKEN_CLASSIFY) { |
| 354 | continue |
| 355 | } |
| 356 | typ := "ner" |
| 357 | if cfg.IsPatternDetector() { |
| 358 | typ = "pattern" |
| 359 | } |
| 360 | detectorModels = append(detectorModels, map[string]any{ |
| 361 | "name": cfg.Name, |
| 362 | "backend": cfg.Backend, |
| 363 | "type": typ, |
| 364 | // Whether this detector is in the instance-wide default set. |
| 365 | "default": defaultSet[cfg.Name], |
no test coverage detected