simpleaudit-studio 0.4.0__tar.gz → 0.4.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/PKG-INFO +1 -1
  2. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/engine.py +69 -33
  3. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_engine_integration.py +70 -3
  4. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/pyproject.toml +2 -1
  5. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/uv.lock +3 -3
  6. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/.dockerignore +0 -0
  7. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/.env.example +0 -0
  8. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/.env.local.example +0 -0
  9. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/.github/workflows/ci.yml +0 -0
  10. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/.github/workflows/docker.yml +0 -0
  11. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/.github/workflows/publish.yml +0 -0
  12. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/.gitignore +0 -0
  13. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/Dockerfile +0 -0
  14. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/LICENSE +0 -0
  15. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/README.md +0 -0
  16. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/accounts/__init__.py +0 -0
  17. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/accounts/admin.py +0 -0
  18. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/accounts/admin_urls.py +0 -0
  19. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/accounts/apps.py +0 -0
  20. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/accounts/auth_urls.py +0 -0
  21. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/accounts/migrations/0001_initial.py +0 -0
  22. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/accounts/migrations/0002_user_preferences.py +0 -0
  23. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/accounts/migrations/__init__.py +0 -0
  24. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/accounts/models.py +0 -0
  25. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/accounts/project_urls.py +0 -0
  26. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/accounts/serializers.py +0 -0
  27. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/accounts/services.py +0 -0
  28. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/accounts/views.py +0 -0
  29. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/accounts/workos_auth.py +0 -0
  30. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/audits/__init__.py +0 -0
  31. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/audits/admin.py +0 -0
  32. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/audits/apps.py +0 -0
  33. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/audits/comparison.py +0 -0
  34. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/audits/events.py +0 -0
  35. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/audits/experiments.py +0 -0
  36. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/audits/migrations/0001_initial.py +0 -0
  37. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/audits/migrations/0002_strip_api_keys_from_snapshots.py +0 -0
  38. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/audits/migrations/0003_judges.py +0 -0
  39. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/audits/migrations/0004_judge_model_per_run.py +0 -0
  40. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/audits/migrations/__init__.py +0 -0
  41. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/audits/models.py +0 -0
  42. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/audits/monitors.py +0 -0
  43. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/audits/serializers.py +0 -0
  44. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/audits/services.py +0 -0
  45. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/audits/urls.py +0 -0
  46. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/audits/views.py +0 -0
  47. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/config/__init__.py +0 -0
  48. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/config/asgi.py +0 -0
  49. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/config/settings.py +0 -0
  50. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/config/urls.py +0 -0
  51. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/config/wsgi.py +0 -0
  52. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/deploy/compose/Dockerfile +0 -0
  53. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/deploy/mock_openai_server.py +0 -0
  54. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/deploy/postgres-init.sql +0 -0
  55. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/docker-compose.yml +0 -0
  56. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/docs/architecture.md +0 -0
  57. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/docs/deployment.md +0 -0
  58. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/docs/domain-model.md +0 -0
  59. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/e2e/test_ui.py +0 -0
  60. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/__init__.py +0 -0
  61. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/admin.py +0 -0
  62. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/apps.py +0 -0
  63. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/codegen.py +0 -0
  64. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/context_processors.py +0 -0
  65. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/db.py +0 -0
  66. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/exceptions.py +0 -0
  67. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/fixtures/demo_audit_results.json +0 -0
  68. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/hashing.py +0 -0
  69. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/health.py +0 -0
  70. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/health_api.py +0 -0
  71. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/logging.py +0 -0
  72. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/management/__init__.py +0 -0
  73. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/management/commands/__init__.py +0 -0
  74. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/management/commands/bootstrap_platform.py +0 -0
  75. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/management/commands/dev_server.py +0 -0
  76. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/management/commands/purge_test_data.py +0 -0
  77. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/management/commands/run_monitors.py +0 -0
  78. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/management/commands/run_worker.py +0 -0
  79. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/management/commands/seed_demo_audits.py +0 -0
  80. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/management/commands/seed_platform.py +0 -0
  81. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/management/commands/setup_local.py +0 -0
  82. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/middleware.py +0 -0
  83. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/minimal_config.py +0 -0
  84. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/readiness.py +0 -0
  85. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/runs_table.py +0 -0
  86. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/seed.py +0 -0
  87. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/seo.py +0 -0
  88. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/simpleaudit_package.py +0 -0
  89. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/startup_checks.py +0 -0
  90. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/templatetags/__init__.py +0 -0
  91. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/templatetags/json_filters.py +0 -0
  92. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/__init__.py +0 -0
  93. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/factories.py +0 -0
  94. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_admin_api.py +0 -0
  95. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_admin_page.py +0 -0
  96. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_api_e2e.py +0 -0
  97. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_audit_archive.py +0 -0
  98. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_audit_clone.py +0 -0
  99. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_audit_events.py +0 -0
  100. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_audit_poll_results.py +0 -0
  101. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_audit_rename.py +0 -0
  102. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_audit_results_live.py +0 -0
  103. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_audit_run_freeze.py +0 -0
  104. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_audit_sse.py +0 -0
  105. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_audit_submission.py +0 -0
  106. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_audit_timing.py +0 -0
  107. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_auth_projects.py +0 -0
  108. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_bootstrap.py +0 -0
  109. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_codegen.py +0 -0
  110. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_comparison.py +0 -0
  111. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_connection_delete.py +0 -0
  112. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_connection_sharing.py +0 -0
  113. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_db_resilience.py +0 -0
  114. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_experiments.py +0 -0
  115. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_health.py +0 -0
  116. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_health_panel.py +0 -0
  117. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_judges.py +0 -0
  118. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_middleware.py +0 -0
  119. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_minimal_config.py +0 -0
  120. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_model_registry.py +0 -0
  121. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_monitors.py +0 -0
  122. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_profile.py +0 -0
  123. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_profile_ui.py +0 -0
  124. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_purge_test_data.py +0 -0
  125. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_runs_table.py +0 -0
  126. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_scenario_import_export.py +0 -0
  127. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_scenarios.py +0 -0
  128. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_seed_platform.py +0 -0
  129. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_smoke_all_pages.py +0 -0
  130. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_snapshot_secrets.py +0 -0
  131. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_workspace_archive.py +0 -0
  132. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_workspaces.py +0 -0
  133. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_workspaces_ui.py +0 -0
  134. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/test_write_guard.py +0 -0
  135. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/tests/utils.py +0 -0
  136. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/ui.py +0 -0
  137. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/infra/worker.py +0 -0
  138. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/judges/__init__.py +0 -0
  139. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/judges/admin.py +0 -0
  140. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/judges/apps.py +0 -0
  141. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/judges/migrations/0001_judges.py +0 -0
  142. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/judges/migrations/0002_judge_model_per_run.py +0 -0
  143. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/judges/migrations/0003_composable_judges.py +0 -0
  144. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/judges/migrations/__init__.py +0 -0
  145. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/judges/models.py +0 -0
  146. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/judges/services.py +0 -0
  147. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/judges/views.py +0 -0
  148. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/manage.py +0 -0
  149. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/model_registry/__init__.py +0 -0
  150. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/model_registry/admin.py +0 -0
  151. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/model_registry/apps.py +0 -0
  152. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/model_registry/migrations/0001_initial.py +0 -0
  153. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/model_registry/migrations/0002_descriptions.py +0 -0
  154. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/model_registry/migrations/0003_modelconnection_shared_with_and_more.py +0 -0
  155. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/model_registry/migrations/__init__.py +0 -0
  156. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/model_registry/models.py +0 -0
  157. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/model_registry/serializers.py +0 -0
  158. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/model_registry/services.py +0 -0
  159. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/model_registry/urls.py +0 -0
  160. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/model_registry/views.py +0 -0
  161. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/scenarios/__init__.py +0 -0
  162. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/scenarios/admin.py +0 -0
  163. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/scenarios/apps.py +0 -0
  164. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/scenarios/migrations/0001_initial.py +0 -0
  165. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/scenarios/migrations/0002_add_severity_ceiling_documents_file_uri.py +0 -0
  166. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/scenarios/migrations/__init__.py +0 -0
  167. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/scenarios/models.py +0 -0
  168. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/scenarios/serializers.py +0 -0
  169. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/scenarios/services.py +0 -0
  170. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/scenarios/urls.py +0 -0
  171. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/scenarios/views.py +0 -0
  172. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/simpleaudit_studio/__init__.py +0 -0
  173. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/simpleaudit_studio/cli.py +0 -0
  174. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/static/favicon-16x16.svg +0 -0
  175. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/static/favicon-32x32.svg +0 -0
  176. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/static/favicon.svg +0 -0
  177. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/static/js/diff.min.js +0 -0
  178. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/static/js/version-diff.js +0 -0
  179. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/static/logo.png +0 -0
  180. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/static/logo.svg +0 -0
  181. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/static/og-image.png +0 -0
  182. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/404.html +0 -0
  183. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/admin.html +0 -0
  184. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/auth/login.html +0 -0
  185. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/auth/register.html +0 -0
  186. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/auth/workos_login.html +0 -0
  187. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/auth/workos_verify.html +0 -0
  188. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/base.html +0 -0
  189. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/compare.html +0 -0
  190. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/dashboard.html +0 -0
  191. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/experiment_detail.html +0 -0
  192. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/experiment_new.html +0 -0
  193. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/experiment_review.html +0 -0
  194. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/experiments.html +0 -0
  195. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/health.html +0 -0
  196. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/judge_detail.html +0 -0
  197. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/judges.html +0 -0
  198. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/models.html +0 -0
  199. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/monitor_detail.html +0 -0
  200. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/monitors.html +0 -0
  201. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/partials/auth_header.html +0 -0
  202. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/partials/chip_input.html +0 -0
  203. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/partials/compare_run_header.html +0 -0
  204. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/partials/footer.html +0 -0
  205. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/partials/judge_picker.html +0 -0
  206. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/partials/local_time_js.html +0 -0
  207. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/partials/model_pickers.html +0 -0
  208. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/partials/multi_filter.html +0 -0
  209. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/partials/need_help.html +0 -0
  210. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/partials/not_found.html +0 -0
  211. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/partials/pinned_version.html +0 -0
  212. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/partials/result_rep_panel.html +0 -0
  213. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/partials/run_results.html +0 -0
  214. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/partials/run_settings.html +0 -0
  215. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/partials/run_settings_js.html +0 -0
  216. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/partials/severity_badge.html +0 -0
  217. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/partials/sidebar.html +0 -0
  218. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/partials/text_file_modal.html +0 -0
  219. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/partials/tooltips.html +0 -0
  220. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/partials/ui_js.html +0 -0
  221. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/partials/version_badge.html +0 -0
  222. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/partials/version_diff_js.html +0 -0
  223. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/partials/version_diff_modal.html +0 -0
  224. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/profile.html +0 -0
  225. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/public/base_public.html +0 -0
  226. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/public/landing.html +0 -0
  227. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/run_detail.html +0 -0
  228. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/run_result.html +0 -0
  229. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/scenarios.html +0 -0
  230. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/seo/head.html +0 -0
  231. {simpleaudit_studio-0.4.0 → simpleaudit_studio-0.4.2}/templates/workspaces.html +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: simpleaudit-studio
3
- Version: 0.4.0
3
+ Version: 0.4.2
4
4
  Summary: Production AI model audit platform — one-liner demo mode via uvx
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -140,6 +140,33 @@ def _split_endpoint_params(params: dict[str, Any]) -> tuple[dict | None, dict |
140
140
  return (gen_params or None), (client_kwargs or None)
141
141
 
142
142
 
143
+ # A slow or stuck endpoint must fail and be retried, not hang a run: the
144
+ # OpenAI client's own default is 600 s per request with 2 retries, and
145
+ # SimpleAudit retries on top. An endpoint's default_parameters can set
146
+ # "timeout" / "max_retries" to override these.
147
+ CLIENT_TIMEOUT_S = 180
148
+ CLIENT_MAX_RETRIES = 1
149
+ _CLIENT_DEFAULTS: dict[str, dict] = {}
150
+
151
+
152
+ def _client_defaults(provider: str) -> dict:
153
+ """``timeout`` / ``max_retries`` client kwargs, when the provider's client
154
+ takes them (probed once by building one; construction opens no connection).
155
+ Providers that don't, or can't be built here, get none."""
156
+ cached = _CLIENT_DEFAULTS.get(provider)
157
+ if cached is None:
158
+ defaults = {"timeout": CLIENT_TIMEOUT_S, "max_retries": CLIENT_MAX_RETRIES}
159
+ try:
160
+ from any_llm import AnyLLM
161
+
162
+ AnyLLM.create(provider, api_key="probe", **defaults)
163
+ cached = defaults
164
+ except Exception: # noqa: BLE001 - unsupported kwargs or provider extras not installed
165
+ cached = {}
166
+ _CLIENT_DEFAULTS[provider] = cached
167
+ return dict(cached)
168
+
169
+
143
170
  def _auditor_kwargs_from_snapshot(snapshot: dict[str, Any], resolve_key=snapshot_api_key) -> dict[str, Any]:
144
171
  """Map a frozen endpoint snapshot onto ModelAuditor constructor kwargs.
145
172
 
@@ -159,12 +186,13 @@ def _auditor_kwargs_from_snapshot(snapshot: dict[str, Any], resolve_key=snapshot
159
186
  # same convention the engine's own preflight probe uses (api_key="probe").
160
187
  if not api_key:
161
188
  api_key = "no-auth"
189
+ provider = _normalize_provider(snapshot.get("provider"), base_url)
162
190
  return {
163
191
  "model": snapshot.get("model_id"),
164
- "provider": _normalize_provider(snapshot.get("provider"), base_url),
192
+ "provider": provider,
165
193
  "base_url": base_url,
166
194
  "api_key": api_key,
167
- "kwargs": client_kwargs,
195
+ "kwargs": {**_client_defaults(provider), **(client_kwargs or {})} or None,
168
196
  "gen_params": gen_params,
169
197
  }
170
198
 
@@ -262,6 +290,30 @@ def build_model_auditor(*, target: dict, auditor: dict, judge: dict, generation:
262
290
  return instance, language
263
291
 
264
292
 
293
+ def scenario_dict(
294
+ *,
295
+ name: str,
296
+ description: str,
297
+ expected_behavior: list[str] | None = None,
298
+ test_prompt: str | None = None,
299
+ severity_ceiling: str = "",
300
+ documents: list | None = None,
301
+ file_uri=None,
302
+ category: str = "",
303
+ metadata: dict | None = None,
304
+ ) -> dict[str, Any]:
305
+ """A scenario in SimpleAudit's own format (what ``ModelAuditor.run`` and
306
+ ``AuditExperiment`` take), with empty fields left out. The designed
307
+ severity goes in ``severity``; judge notes ride in ``metadata``."""
308
+ scenario: dict[str, Any] = {"name": name, "description": description}
309
+ optional = {
310
+ "expected_behavior": expected_behavior, "test_prompt": test_prompt, "severity": severity_ceiling,
311
+ "documents": documents, "file_uri": file_uri, "category": category, "metadata": metadata,
312
+ }
313
+ scenario.update({k: v for k, v in optional.items() if v})
314
+ return scenario
315
+
316
+
265
317
  def run_scenario(
266
318
  *,
267
319
  name: str,
@@ -295,26 +347,20 @@ def run_scenario(
295
347
  auditor_instance, language = build_model_auditor(
296
348
  target=target, auditor=auditor, judge=judge, generation=generation
297
349
  )
350
+ scenario = scenario_dict(
351
+ name=name, description=description, expected_behavior=expected_behavior, test_prompt=test_prompt,
352
+ severity_ceiling=severity_ceiling, documents=documents, file_uri=file_uri, category=category,
353
+ metadata=metadata,
354
+ )
298
355
  try:
299
- result = asyncio.run(
300
- auditor_instance.run_scenario(
301
- name=name,
302
- description=description,
303
- expected_behavior=expected_behavior,
304
- test_prompt=test_prompt,
305
- severity=severity_ceiling or None,
306
- documents=documents or None,
307
- file_uri=file_uri,
308
- category=category or None,
309
- metadata=metadata or {},
310
- language=language,
311
- on_turn=on_turn,
312
- )
313
- )
356
+ # run_async maps the scenario dict onto run_scenario (file_uri,
357
+ # documents, judge notes, the scenario facts a judge's post-processor
358
+ # reads), the same way AuditExperiment does for repetitions.
359
+ results = asyncio.run(auditor_instance.run_async([scenario], language=language, on_turn=on_turn))
314
360
  except Exception as exc:
315
361
  raise EngineError(f"Scenario execution crashed: {type(exc).__name__}: {exc}") from exc
316
362
 
317
- payload = result.to_dict()
363
+ payload = results[0].to_dict()
318
364
  payload["_language"] = language
319
365
  return payload
320
366
 
@@ -369,21 +415,11 @@ def run_scenario_repeated(
369
415
 
370
416
  kwargs, language = auditor_kwargs(target=target, auditor=auditor, judge=judge, generation=generation)
371
417
  max_turns = kwargs["max_turns"]
372
- scenario: dict[str, Any] = {"name": name, "description": description}
373
- if expected_behavior:
374
- scenario["expected_behavior"] = expected_behavior
375
- if test_prompt:
376
- scenario["test_prompt"] = test_prompt
377
- if severity_ceiling:
378
- scenario["severity"] = severity_ceiling
379
- if documents:
380
- scenario["documents"] = documents
381
- if file_uri:
382
- scenario["file_uri"] = file_uri
383
- if category:
384
- scenario["category"] = category
385
- if metadata:
386
- scenario["metadata"] = metadata
418
+ scenario = scenario_dict(
419
+ name=name, description=description, expected_behavior=expected_behavior, test_prompt=test_prompt,
420
+ severity_ceiling=severity_ceiling, documents=documents, file_uri=file_uri, category=category,
421
+ metadata=metadata,
422
+ )
387
423
 
388
424
  # The model entry carries every ModelAuditor kwarg (target, auditor and
389
425
  # judge alike): AuditExperiment passes it through _merge_common to
@@ -140,8 +140,9 @@ class AuditorKwargsTest(TestCase):
140
140
  self.assertEqual(language, "Norwegian")
141
141
  self.assertEqual((kwargs["model"], kwargs["auditor_model"], kwargs["judge_model"]), ("tgt", "aud", "jdg"))
142
142
  self.assertEqual(kwargs["judge_base_url"], "http://jdg.local/v1")
143
- self.assertEqual(kwargs["auditor_kwargs"], {"timeout": 5})
144
- self.assertEqual(kwargs["judge_kwargs"], {"timeout": 9})
143
+ # An endpoint's own timeout wins over the default; max_retries is the default.
144
+ self.assertEqual(kwargs["auditor_kwargs"], {"timeout": 5, "max_retries": 1})
145
+ self.assertEqual(kwargs["judge_kwargs"], {"timeout": 9, "max_retries": 1})
145
146
  self.assertEqual(kwargs["judge_params"], {"temperature": 0, "top_p": 1})
146
147
  self.assertEqual(kwargs["target_params"], {"temperature": 0.1})
147
148
  self.assertEqual(kwargs["system_prompt"], "Be brief.")
@@ -196,7 +197,7 @@ class AuditorKwargsTest(TestCase):
196
197
  entry = captured["entry"]
197
198
  self.assertEqual((entry["model"], entry["auditor_model"], entry["judge_model"]), ("tgt", "aud", "jdg"))
198
199
  self.assertEqual(entry["judge_base_url"], "http://jdg.local/v1")
199
- self.assertEqual(entry["judge_kwargs"], {"timeout": 9})
200
+ self.assertEqual(entry["judge_kwargs"], {"timeout": 9, "max_retries": 1})
200
201
 
201
202
 
202
203
  class ProviderNormalizationTest(TestCase):
@@ -772,3 +773,69 @@ class ResumableExecutionTest(TestCase):
772
773
  submit.assert_not_called()
773
774
  run.refresh_from_db()
774
775
  self.assertEqual(run.status, AuditRun.Status.COMPLETED)
776
+
777
+
778
+ class ClientDefaultsTest(TestCase):
779
+ """A stuck endpoint must not hang a run: requests get a bounded timeout."""
780
+
781
+ def test_default_timeout_and_endpoint_override(self):
782
+ from infra.engine import CLIENT_TIMEOUT_S, auditor_kwargs
783
+
784
+ kwargs, _ = auditor_kwargs(target=_snap("t"), auditor=_snap("a", default_parameters={"max_retries": 4}),
785
+ judge=_snap("j"))
786
+ self.assertEqual(kwargs["target_kwargs"], {"timeout": CLIENT_TIMEOUT_S, "max_retries": 1})
787
+ self.assertEqual(kwargs["auditor_kwargs"], {"timeout": CLIENT_TIMEOUT_S, "max_retries": 4})
788
+
789
+ def test_provider_without_support_gets_none(self):
790
+ from infra import engine
791
+
792
+ engine._CLIENT_DEFAULTS.pop("nosuchprovider", None)
793
+ self.assertEqual(engine._client_defaults("nosuchprovider"), {})
794
+
795
+
796
+ class RealAuditorScenarioTest(TestCase):
797
+ """engine.run_scenario against the real ModelAuditor (fake model clients):
798
+ every scenario field Studio stores must reach SimpleAudit without a
799
+ TypeError. Regression: severity / category / metadata were passed as
800
+ run_scenario keywords, which it doesn't take, so every run failed."""
801
+
802
+ def _client(self, replies):
803
+ from types import SimpleNamespace
804
+
805
+ calls = []
806
+
807
+ async def acompletion(**kwargs):
808
+ calls.append(kwargs)
809
+ text = replies(kwargs)
810
+ return SimpleNamespace(choices=[SimpleNamespace(message=SimpleNamespace(content=text))], usage=None)
811
+
812
+ return SimpleNamespace(acompletion=acompletion), calls
813
+
814
+ def test_all_scenario_fields_reach_simpleaudit(self):
815
+ import json as _json
816
+
817
+ from simpleaudit.model_auditor import ModelAuditor
818
+
819
+ from infra.engine import run_scenario
820
+
821
+ verdict = {"severity": "pass", "issues_found": [], "positive_behaviors": ["ok"], "summary": "Fine.",
822
+ "recommendations": []}
823
+ client, calls = self._client(lambda kw: _json.dumps(verdict) if kw.get("response_format") else "Hello.")
824
+ with mock.patch.object(ModelAuditor, "_create_anyllm_client", return_value=client):
825
+ payload = run_scenario(
826
+ name="dose", description="Ask about a dose.", expected_behavior=["Refuse"], test_prompt="Dose?",
827
+ target=_snap("t"), auditor=_snap("a"), judge=_snap("j"), generation={"max_turns": 1},
828
+ severity_ceiling="high", documents=["Leaflet: max 2 tablets."], category="health",
829
+ metadata={"judge_notes": ["Dosage advice is a fail."]},
830
+ )
831
+ self.assertEqual(payload["severity"], "pass")
832
+ judge_call = next(c for c in calls if c.get("response_format"))
833
+ judge_text = " ".join(m["content"] for m in judge_call["messages"] if isinstance(m.get("content"), str))
834
+ self.assertIn("Dosage advice is a fail.", judge_text) # judge notes reached the judge
835
+
836
+ def test_scenario_dict_leaves_out_empty_fields(self):
837
+ from infra.engine import scenario_dict
838
+
839
+ self.assertEqual(scenario_dict(name="n", description="d", test_prompt="", metadata={}),
840
+ {"name": "n", "description": "d"})
841
+ self.assertEqual(scenario_dict(name="n", description="d", severity_ceiling="high")["severity"], "high")
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "simpleaudit-studio"
7
- version = "0.4.0"
7
+ version = "0.4.2"
8
8
  description = "Production AI model audit platform — one-liner demo mode via uvx"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -59,6 +59,7 @@ packages = [
59
59
  "infra",
60
60
  "scenarios",
61
61
  "model_registry",
62
+ "judges",
62
63
  "deploy",
63
64
  "templates",
64
65
  "static",
@@ -1028,8 +1028,8 @@ name = "httpcore2"
1028
1028
  version = "2.13.1"
1029
1029
  source = { registry = "https://pypi.org/simple" }
1030
1030
  dependencies = [
1031
- { name = "h11" },
1032
- { name = "truststore" },
1031
+ { name = "h11", marker = "python_full_version < '3.12' or sys_platform != 'emscripten'" },
1032
+ { name = "truststore", marker = "python_full_version < '3.12' or sys_platform != 'emscripten'" },
1033
1033
  ]
1034
1034
  sdist = { url = "https://files.pythonhosted.org/packages/cb/f3/1db7aa2bc2524062192bb0e0323969492d1883152a232fe36eea65f4e35c/httpcore2-2.13.1.tar.gz", hash = "sha256:e0aa977abe17e69a3b820a24542a6fa88702676d83880b8d194dcd18408e5103", size = 68071, upload-time = "2026-09-23T07:47:22.372Z" }
1035
1035
  wheels = [
@@ -2163,7 +2163,7 @@ wheels = [
2163
2163
 
2164
2164
  [[package]]
2165
2165
  name = "simpleaudit-studio"
2166
- version = "0.4.0"
2166
+ version = "0.4.2"
2167
2167
  source = { editable = "." }
2168
2168
  dependencies = [
2169
2169
  { name = "cronsim" },