classifyre-cli 0.4.106__tar.gz → 0.4.108__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 (287) hide show
  1. classifyre_cli-0.4.108/.turbo/turbo-build.log +3 -0
  2. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/PKG-INFO +2 -2
  3. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/package.json +1 -1
  4. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/pyproject.toml +1 -1
  5. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/file_evaluation/runner.py +7 -0
  6. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/main.py +25 -10
  7. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/test_custom_detector_examples_runtime.py +6 -4
  8. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_file_evaluation_runner.py +8 -0
  9. classifyre_cli-0.4.108/tests/test_main.py +78 -0
  10. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/uv.lock +50 -64
  11. classifyre_cli-0.4.106/.turbo/turbo-build.log +0 -3
  12. classifyre_cli-0.4.106/tests/test_main.py +0 -36
  13. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/.gitignore +0 -0
  14. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/.python-version +0 -0
  15. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/README.md +0 -0
  16. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/main.py +0 -0
  17. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/scripts/generate_models.py +0 -0
  18. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/__init__.py +0 -0
  19. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/config.py +0 -0
  20. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/__init__.py +0 -0
  21. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/base.py +0 -0
  22. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/broken_links/__init__.py +0 -0
  23. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/broken_links/detector.py +0 -0
  24. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/config.py +0 -0
  25. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/content/__init__.py +0 -0
  26. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/custom/__init__.py +0 -0
  27. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/custom/detector.py +0 -0
  28. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/custom/extractor.py +0 -0
  29. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/custom/runners/__init__.py +0 -0
  30. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/custom/runners/_base.py +0 -0
  31. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/custom/runners/_factory.py +0 -0
  32. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/custom/runners/_gliner2.py +0 -0
  33. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/custom/runners/_image_classification.py +0 -0
  34. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/custom/runners/_llm.py +0 -0
  35. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/custom/runners/_object_detection.py +0 -0
  36. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/custom/runners/_regex.py +0 -0
  37. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/custom/runners/_text_classification.py +0 -0
  38. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/custom/trainer.py +0 -0
  39. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/dependencies.py +0 -0
  40. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/engine_version.py +0 -0
  41. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/pii/__init__.py +0 -0
  42. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/pii/detector.py +0 -0
  43. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/secrets/__init__.py +0 -0
  44. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/secrets/detector.py +0 -0
  45. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/threat/__init__.py +0 -0
  46. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/threat/code_security_detector.py +0 -0
  47. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/detectors/threat/yara_detector.py +0 -0
  48. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/file_evaluation/__init__.py +0 -0
  49. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/models/generated_detectors.py +0 -0
  50. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/models/generated_input.py +0 -0
  51. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/models/generated_single_asset_scan_results.py +0 -0
  52. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/outputs/__init__.py +0 -0
  53. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/outputs/base.py +0 -0
  54. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/outputs/console.py +0 -0
  55. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/outputs/factory.py +0 -0
  56. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/outputs/file.py +0 -0
  57. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/outputs/rest.py +0 -0
  58. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/pipeline/__init__.py +0 -0
  59. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/pipeline/content_provider.py +0 -0
  60. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/pipeline/detector_pipeline.py +0 -0
  61. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/pipeline/parsed_content_provider.py +0 -0
  62. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/pipeline/payload_window.py +0 -0
  63. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/pipeline/scan_cache.py +0 -0
  64. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/pipeline/text_artifact.py +0 -0
  65. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/pipeline/worker_pool.py +0 -0
  66. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/__init__.py +0 -0
  67. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/asset_metadata.py +0 -0
  68. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/atlassian_common.py +0 -0
  69. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/azure_blob_storage/__init__.py +0 -0
  70. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/azure_blob_storage/source.py +0 -0
  71. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/base.py +0 -0
  72. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/confluence/__init__.py +0 -0
  73. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/confluence/source.py +0 -0
  74. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/databricks/__init__.py +0 -0
  75. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/databricks/source.py +0 -0
  76. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/delta_lake/__init__.py +0 -0
  77. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/delta_lake/source.py +0 -0
  78. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/dependencies.py +0 -0
  79. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/dropbox/__init__.py +0 -0
  80. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/dropbox/auth.py +0 -0
  81. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/dropbox/source.py +0 -0
  82. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/elasticsearch/__init__.py +0 -0
  83. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/elasticsearch/source.py +0 -0
  84. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/email/__init__.py +0 -0
  85. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/email/source.py +0 -0
  86. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/git/__init__.py +0 -0
  87. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/git/source.py +0 -0
  88. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/google_cloud_storage/__init__.py +0 -0
  89. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/google_cloud_storage/source.py +0 -0
  90. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/google_workspace/__init__.py +0 -0
  91. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/google_workspace/source.py +0 -0
  92. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/hive/__init__.py +0 -0
  93. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/hive/source.py +0 -0
  94. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/hugging_face/__init__.py +0 -0
  95. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/hugging_face/source.py +0 -0
  96. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/iceberg/__init__.py +0 -0
  97. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/iceberg/source.py +0 -0
  98. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/jira/__init__.py +0 -0
  99. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/jira/source.py +0 -0
  100. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/kafka/__init__.py +0 -0
  101. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/kafka/rest.py +0 -0
  102. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/kafka/source.py +0 -0
  103. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/lakehouse_base.py +0 -0
  104. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/local_folder/__init__.py +0 -0
  105. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/local_folder/source.py +0 -0
  106. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/meilisearch/__init__.py +0 -0
  107. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/meilisearch/source.py +0 -0
  108. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/microsoft_365/__init__.py +0 -0
  109. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/microsoft_365/source.py +0 -0
  110. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/mongodb/__init__.py +0 -0
  111. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/mongodb/source.py +0 -0
  112. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/mssql/__init__.py +0 -0
  113. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/mssql/source.py +0 -0
  114. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/mysql/__init__.py +0 -0
  115. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/mysql/source.py +0 -0
  116. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/neo4j/__init__.py +0 -0
  117. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/neo4j/source.py +0 -0
  118. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/notion/__init__.py +0 -0
  119. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/notion/client.py +0 -0
  120. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/notion/source.py +0 -0
  121. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/object_storage/base.py +0 -0
  122. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/opensearch/__init__.py +0 -0
  123. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/opensearch/source.py +0 -0
  124. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/oracle/__init__.py +0 -0
  125. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/oracle/source.py +0 -0
  126. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/postgresql/__init__.py +0 -0
  127. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/postgresql/source.py +0 -0
  128. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/powerbi/__init__.py +0 -0
  129. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/powerbi/source.py +0 -0
  130. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/recipe_normalizer.py +0 -0
  131. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/reddit/__init__.py +0 -0
  132. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/reddit/source.py +0 -0
  133. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/s3_client.py +0 -0
  134. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/s3_compatible_storage/README.md +0 -0
  135. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/s3_compatible_storage/__init__.py +0 -0
  136. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/s3_compatible_storage/source.py +0 -0
  137. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/sandbox/__init__.py +0 -0
  138. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/sandbox/source.py +0 -0
  139. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/search_engine_base.py +0 -0
  140. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/servicedesk/__init__.py +0 -0
  141. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/servicedesk/source.py +0 -0
  142. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/slack/__init__.py +0 -0
  143. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/slack/source.py +0 -0
  144. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/snowflake/__init__.py +0 -0
  145. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/snowflake/source.py +0 -0
  146. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/sqlite/__init__.py +0 -0
  147. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/sqlite/source.py +0 -0
  148. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/tableau/__init__.py +0 -0
  149. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/tableau/source.py +0 -0
  150. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/tabular_base.py +0 -0
  151. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/tabular_utils.py +0 -0
  152. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/wordpress/__init__.py +0 -0
  153. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/wordpress/source.py +0 -0
  154. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/youtube/__init__.py +0 -0
  155. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/sources/youtube/source.py +0 -0
  156. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/telemetry.py +0 -0
  157. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/utils/__init__.py +0 -0
  158. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/utils/archive_extraction.py +0 -0
  159. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/utils/content_extraction.py +0 -0
  160. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/utils/dependency_groups.py +0 -0
  161. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/utils/embedded_files.py +0 -0
  162. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/utils/external_video.py +0 -0
  163. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/utils/file_metadata.py +0 -0
  164. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/utils/file_parser.py +0 -0
  165. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/utils/file_to_images.py +0 -0
  166. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/utils/hashing.py +0 -0
  167. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/utils/legacy_office.py +0 -0
  168. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/utils/payload.py +0 -0
  169. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/utils/range_reader.py +0 -0
  170. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/utils/resources.py +0 -0
  171. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/utils/transcription.py +0 -0
  172. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/utils/uv_sync.py +0 -0
  173. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/utils/validation.py +0 -0
  174. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/src/utils/video_processing.py +0 -0
  175. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/__init__.py +0 -0
  176. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/_lakehouse_fakes.py +0 -0
  177. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/conftest.py +0 -0
  178. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/__init__.py +0 -0
  179. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/broken_links/test_broken_links_detector.py +0 -0
  180. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/conftest.py +0 -0
  181. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/content/__init__.py +0 -0
  182. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/custom/__init__.py +0 -0
  183. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/custom/conftest.py +0 -0
  184. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/custom/test_gliner2_classification.py +0 -0
  185. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/custom/test_invoice_extraction.py +0 -0
  186. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/custom/test_llm_runner.py +0 -0
  187. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/custom/test_pipeline_integration.py +0 -0
  188. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/custom/test_regex_runner.py +0 -0
  189. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/custom/test_runner_hardening.py +0 -0
  190. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/custom/test_transformer_runners.py +0 -0
  191. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/pii/__init__.py +0 -0
  192. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/pii/conftest.py +0 -0
  193. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/pii/sample_invoice.pdf +0 -0
  194. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/pii/test_pii_chunking.py +0 -0
  195. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/pii/test_pii_detector.py +0 -0
  196. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/pii/test_pii_detector_extended.py +0 -0
  197. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/pii/test_pii_regional_entities.py +0 -0
  198. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/pii/test_pii_severity.py +0 -0
  199. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/secrets/__init__.py +0 -0
  200. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/secrets/test_secrets_detector.py +0 -0
  201. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/secrets/test_secrets_detector_extended.py +0 -0
  202. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/test_base_detector.py +0 -0
  203. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/test_detector_catalog_commercial.py +0 -0
  204. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/test_detector_pipeline_types.py +0 -0
  205. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/test_detector_schema_examples.py +0 -0
  206. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/test_detector_types.py +0 -0
  207. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/test_phase2_detectors.py +0 -0
  208. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/test_registry.py +0 -0
  209. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/threat/__init__.py +0 -0
  210. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/threat/test_code_security_detector.py +0 -0
  211. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/detectors/threat/test_yara_detector.py +0 -0
  212. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/integration/test_wordpress_broken_links_detector.py +0 -0
  213. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/integration/test_wordpress_links_assets.py +0 -0
  214. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/pipeline/test_detector_outcomes.py +0 -0
  215. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/pipeline/test_detector_pipeline.py +0 -0
  216. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/pipeline/test_worker_pool.py +0 -0
  217. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_arrow_ipc_payloads.py +0 -0
  218. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_assets_metadata_catalog.py +0 -0
  219. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_azure_blob_storage_source.py +0 -0
  220. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_base_source_attachment.py +0 -0
  221. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_base_source_sampling.py +0 -0
  222. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_byte_valued_fields.py +0 -0
  223. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_config.py +0 -0
  224. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_confluence_source.py +0 -0
  225. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_custom_extractor.py +0 -0
  226. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_databricks_source.py +0 -0
  227. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_delta_lake_source.py +0 -0
  228. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_dependency_groups.py +0 -0
  229. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_dropbox_auth_command.py +0 -0
  230. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_dropbox_source.py +0 -0
  231. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_elasticsearch_source.py +0 -0
  232. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_email_source.py +0 -0
  233. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_git_source.py +0 -0
  234. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_google_cloud_storage_source.py +0 -0
  235. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_google_workspace_source.py +0 -0
  236. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_hashing.py +0 -0
  237. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_hive_source.py +0 -0
  238. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_hugging_face_source.py +0 -0
  239. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_iceberg_source.py +0 -0
  240. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_jira_source.py +0 -0
  241. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_kafka_source.py +0 -0
  242. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_local_folder_source.py +0 -0
  243. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_meilisearch_source.py +0 -0
  244. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_microsoft_365_source.py +0 -0
  245. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_mongodb_source.py +0 -0
  246. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_mssql_source.py +0 -0
  247. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_mysql_source.py +0 -0
  248. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_neo4j_source.py +0 -0
  249. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_notion_source.py +0 -0
  250. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_object_storage_download_efficiency.py +0 -0
  251. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_opensearch_source.py +0 -0
  252. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_oracle_source.py +0 -0
  253. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_outputs.py +0 -0
  254. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_payload_window.py +0 -0
  255. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_payload_window_parquet.py +0 -0
  256. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_postgresql_source.py +0 -0
  257. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_powerbi_source.py +0 -0
  258. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_range_reading.py +0 -0
  259. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_recipe_normalizer.py +0 -0
  260. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_reddit_source.py +0 -0
  261. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_s3_compatible_storage_source.py +0 -0
  262. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_sampling_automatic.py +0 -0
  263. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_sandbox_source.py +0 -0
  264. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_scan_cache.py +0 -0
  265. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_servicedesk_source.py +0 -0
  266. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_slack_source.py +0 -0
  267. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_snowflake_source.py +0 -0
  268. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_source_dependency_groups.py +0 -0
  269. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_source_strategy_conformance.py +0 -0
  270. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_sqlite_source.py +0 -0
  271. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_tableau_source.py +0 -0
  272. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_tabular_automatic_sampling.py +0 -0
  273. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_tabular_utils.py +0 -0
  274. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_uv_sync.py +0 -0
  275. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_wordpress_source.py +0 -0
  276. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_youtube_source.py +0 -0
  277. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/test_youtube_source_integration.py +0 -0
  278. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/utils/test_archive_extraction.py +0 -0
  279. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/utils/test_content_extraction.py +0 -0
  280. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/utils/test_embedded_files.py +0 -0
  281. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/utils/test_file_metadata.py +0 -0
  282. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/utils/test_file_parser.py +0 -0
  283. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/utils/test_file_to_images.py +0 -0
  284. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/utils/test_legacy_office.py +0 -0
  285. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/utils/test_payload.py +0 -0
  286. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/utils/test_transcription.py +0 -0
  287. {classifyre_cli-0.4.106 → classifyre_cli-0.4.108}/tests/utils/test_video_processing.py +0 -0
@@ -0,0 +1,3 @@
1
+ $ uv sync
2
+ Resolved 309 packages in 232ms
3
+ Checked 51 packages in 3ms
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: classifyre-cli
3
- Version: 0.4.106
3
+ Version: 0.4.108
4
4
  Summary: Classifyre CLI — scan and classify unstructured data sources
5
5
  License: MIT
6
6
  Keywords: data,ingestion,metadata,pii,secrets,unstructured
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classifyre/cli",
3
- "version": "0.4.106",
3
+ "version": "0.4.108",
4
4
  "private": true,
5
5
  "scripts": {
6
6
  "build": "uv sync",
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "classifyre-cli"
3
- version = "0.4.106"
3
+ version = "0.4.108"
4
4
  description = "Classifyre CLI — scan and classify unstructured data sources"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -24,8 +24,14 @@ class FileEvaluationRunner:
24
24
  # output so callers can distinguish "misconfigured detector" from
25
25
  # "no findings".
26
26
  self.detector_errors: list[str] = []
27
+ self._detectors: list[Any] | None = None
27
28
 
28
29
  def _build_detectors(self) -> list[Any]:
30
+ # A detector test commonly contains a positive and a counterexample.
31
+ # Keep heavyweight GLiNER/HuggingFace models alive across both files.
32
+ if self._detectors is not None:
33
+ return self._detectors
34
+
29
35
  from ..detectors import get_detector
30
36
  from ..detectors.config import parse_detector_config
31
37
 
@@ -50,6 +56,7 @@ class FileEvaluationRunner:
50
56
  logger.error(f"Failed to initialize detector {detector_type}: {e}")
51
57
  self.detector_errors.append(f"{detector_type}: {e}")
52
58
 
59
+ self._detectors = detectors
53
60
  return detectors
54
61
 
55
62
  @staticmethod
@@ -658,7 +658,7 @@ def run_train_command(args: argparse.Namespace) -> None:
658
658
 
659
659
 
660
660
  def run_evaluate_file_command(args: argparse.Namespace) -> None:
661
- """Evaluate detector configs against one ephemeral local file."""
661
+ """Evaluate detector configs against one file or a directory of samples."""
662
662
  from .file_evaluation import FileEvaluationRunner
663
663
 
664
664
  file_path_str: str | None = args.recipe
@@ -689,15 +689,30 @@ def run_evaluate_file_command(args: argparse.Namespace) -> None:
689
689
 
690
690
  try:
691
691
  runner = FileEvaluationRunner(detectors)
692
- parsed, findings = runner.run(file_path)
693
- if parsed.parse_error:
694
- logger.warning("File parse warning: %s", parsed.parse_error)
695
- output: dict[str, Any] = {
696
- "mime_type": parsed.mime_type,
697
- "findings": [f.model_dump(mode="json") for f in findings],
698
- }
699
- if parsed.parse_error:
700
- output["parse_error"] = parsed.parse_error
692
+ output: dict[str, Any]
693
+ if file_path.is_dir():
694
+ evaluations: list[dict[str, Any]] = []
695
+ for sample_path in sorted(p for p in file_path.iterdir() if p.is_file()):
696
+ parsed, findings = runner.run(sample_path)
697
+ item: dict[str, Any] = {
698
+ "name": sample_path.name,
699
+ "mime_type": parsed.mime_type,
700
+ "findings": [f.model_dump(mode="json") for f in findings],
701
+ }
702
+ if parsed.parse_error:
703
+ item["parse_error"] = parsed.parse_error
704
+ evaluations.append(item)
705
+ output = {"evaluations": evaluations}
706
+ else:
707
+ parsed, findings = runner.run(file_path)
708
+ if parsed.parse_error:
709
+ logger.warning("File parse warning: %s", parsed.parse_error)
710
+ output = {
711
+ "mime_type": parsed.mime_type,
712
+ "findings": [f.model_dump(mode="json") for f in findings],
713
+ }
714
+ if parsed.parse_error:
715
+ output["parse_error"] = parsed.parse_error
701
716
  if runner.detector_errors:
702
717
  output["detector_errors"] = runner.detector_errors
703
718
  print(json.dumps(_sanitize_for_json(output), ensure_ascii=False))
@@ -13,14 +13,16 @@ from src.detectors.custom.runners import GLiNER2Runner, RegexRunner
13
13
  from src.models.generated_detectors import (
14
14
  CustomDetectorConfig,
15
15
  ImageClassificationPipelineSchema,
16
+ LLMPipelineSchema,
16
17
  ObjectDetectionPipelineSchema,
17
18
  TextClassificationPipelineSchema,
18
19
  )
19
20
 
20
- _TRANSFORMER_SCHEMA_TYPES = (
21
+ _EXTERNAL_RUNTIME_SCHEMA_TYPES = (
21
22
  TextClassificationPipelineSchema,
22
23
  ImageClassificationPipelineSchema,
23
24
  ObjectDetectionPipelineSchema,
25
+ LLMPipelineSchema,
24
26
  )
25
27
 
26
28
 
@@ -135,12 +137,12 @@ async def test_regex_example_invoice_pii_detects_iban(custom_examples: list[dict
135
137
  async def test_gliner2_example_all_examples_load_and_detect(custom_examples: list[dict]):
136
138
  """All GLINER2/REGEX examples must parse and run detect() without crashing.
137
139
 
138
- Transformer-based examples (TEXT_CLASSIFICATION, IMAGE_CLASSIFICATION, etc.) are
139
- skipped here they require real model downloads. Covered by test_transformer_runners.py.
140
+ Examples that need model downloads or injected provider credentials are skipped here.
141
+ Their runners have focused coverage in the custom runner test modules.
140
142
  """
141
143
  for example in custom_examples:
142
144
  config = CustomDetectorConfig.model_validate(example["config"])
143
- if isinstance(config.pipeline_schema, _TRANSFORMER_SCHEMA_TYPES):
145
+ if isinstance(config.pipeline_schema, _EXTERNAL_RUNTIME_SCHEMA_TYPES):
144
146
  continue
145
147
 
146
148
  detector = CustomDetector(config)
@@ -46,6 +46,14 @@ def _runner_with(detector: _RecordingDetector) -> FileEvaluationRunner:
46
46
  return runner
47
47
 
48
48
 
49
+ def test_detector_initialization_is_cached_across_batch_files() -> None:
50
+ runner = FileEvaluationRunner([{"type": "NOT_A_DETECTOR", "enabled": True, "config": {}}])
51
+
52
+ assert runner._build_detectors() == []
53
+ assert runner._build_detectors() == []
54
+ assert len(runner.detector_errors) == 1
55
+
56
+
49
57
  def _write_png(path: Path) -> None:
50
58
  pytest.importorskip("PIL")
51
59
  from PIL import Image
@@ -0,0 +1,78 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ import json
5
+ from pathlib import Path
6
+ from unittest.mock import AsyncMock
7
+
8
+ import pytest
9
+
10
+ from src.main import _emit_text_chunks_with_retry, run_evaluate_file_command
11
+
12
+
13
+ @pytest.mark.asyncio
14
+ async def test_emit_text_chunks_retries_before_succeeding(
15
+ monkeypatch: pytest.MonkeyPatch,
16
+ ) -> None:
17
+ sink = type("Sink", (), {})()
18
+ sink.emit_text_chunks = AsyncMock(side_effect=[RuntimeError("temporary outage"), None])
19
+ sleep = AsyncMock()
20
+ monkeypatch.setattr("src.main.asyncio.sleep", sleep)
21
+
22
+ await _emit_text_chunks_with_retry(sink, "asset-1", object(), attempts=3)
23
+
24
+ assert sink.emit_text_chunks.await_count == 2
25
+ sleep.assert_awaited_once_with(0.25)
26
+
27
+
28
+ @pytest.mark.asyncio
29
+ async def test_emit_text_chunks_propagates_exhausted_retries(
30
+ monkeypatch: pytest.MonkeyPatch,
31
+ ) -> None:
32
+ sink = type("Sink", (), {})()
33
+ sink.emit_text_chunks = AsyncMock(side_effect=RuntimeError("API unavailable"))
34
+ monkeypatch.setattr("src.main.asyncio.sleep", AsyncMock())
35
+
36
+ with pytest.raises(RuntimeError, match="API unavailable"):
37
+ await _emit_text_chunks_with_retry(sink, "asset-1", object(), attempts=3)
38
+
39
+ assert sink.emit_text_chunks.await_count == 3
40
+
41
+
42
+ def test_evaluate_file_directory_returns_one_result_per_sample(
43
+ tmp_path: Path,
44
+ monkeypatch: pytest.MonkeyPatch,
45
+ capsys: pytest.CaptureFixture[str],
46
+ ) -> None:
47
+ (tmp_path / "input-001.txt").write_text("counter")
48
+ (tmp_path / "input-000.txt").write_text("positive")
49
+
50
+ calls: list[str] = []
51
+
52
+ class FakeParsed:
53
+ mime_type = "text/plain"
54
+ parse_error = None
55
+
56
+ class FakeFinding:
57
+ def model_dump(self, **_kwargs: object) -> dict[str, str]:
58
+ return {"finding_type": "match"}
59
+
60
+ class FakeRunner:
61
+ def __init__(self, _detectors: list[dict[str, object]]) -> None:
62
+ self.detector_errors: list[str] = []
63
+
64
+ def run(self, sample_path: Path) -> tuple[FakeParsed, list[FakeFinding]]:
65
+ calls.append(sample_path.name)
66
+ findings = [FakeFinding()] if sample_path.name == "input-000.txt" else []
67
+ return FakeParsed(), findings
68
+
69
+ monkeypatch.setattr("src.file_evaluation.FileEvaluationRunner", FakeRunner)
70
+ run_evaluate_file_command(
71
+ argparse.Namespace(recipe=str(tmp_path), detectors_file=None),
72
+ )
73
+
74
+ output = json.loads(capsys.readouterr().out)
75
+ assert calls == ["input-000.txt", "input-001.txt"]
76
+ assert [item["name"] for item in output["evaluations"]] == calls
77
+ assert len(output["evaluations"][0]["findings"]) == 1
78
+ assert output["evaluations"][1]["findings"] == []
@@ -562,30 +562,30 @@ wheels = [
562
562
 
563
563
  [[package]]
564
564
  name = "boto3"
565
- version = "1.43.67"
565
+ version = "1.43.69"
566
566
  source = { registry = "https://pypi.org/simple" }
567
567
  dependencies = [
568
568
  { name = "botocore" },
569
569
  { name = "jmespath" },
570
570
  { name = "s3transfer" },
571
571
  ]
572
- sdist = { url = "https://files.pythonhosted.org/packages/ad/bf/ef5de9b55523bc2141d072fbe6614627088e3e6f97b47850216e99de6a1c/boto3-1.43.67.tar.gz", hash = "sha256:75fe983b70d39cfdc274dc51f9bb02b8a0a104bdad4fa073c1af85a35e707c91", size = 112665, upload-time = "2026-08-07T19:30:20.418Z" }
572
+ sdist = { url = "https://files.pythonhosted.org/packages/45/8f/315e908f5abaab5deb77196117f66c1badc9093b03dc152b0b8231b0112b/boto3-1.43.69.tar.gz", hash = "sha256:76297a0b415849c63575ae08a4f1661b2dc8ee0100f104b86f98aa69b47fa2c7", size = 112666, upload-time = "2026-08-11T19:24:26.281Z" }
573
573
  wheels = [
574
- { url = "https://files.pythonhosted.org/packages/77/0f/b41f8968452dc6bf3b83f15f5e9f76a27fd93e246906aeb2e0555f494375/boto3-1.43.67-py3-none-any.whl", hash = "sha256:082cf9df068168cb44028a1703822374c1eb7e48fa49470d7e8a76f0c977d0bc", size = 140025, upload-time = "2026-08-07T19:30:18.49Z" },
574
+ { url = "https://files.pythonhosted.org/packages/7a/57/67ebb743ab0556c14db656e91e49024f3e1b0585f1a15c2d025176fb3c1e/boto3-1.43.69-py3-none-any.whl", hash = "sha256:4eb494d05b2bd08a7eee61b8ac4c34745c99e9bbce435c91f8d15d372dd8c2db", size = 140024, upload-time = "2026-08-11T19:24:25.022Z" },
575
575
  ]
576
576
 
577
577
  [[package]]
578
578
  name = "botocore"
579
- version = "1.43.67"
579
+ version = "1.43.69"
580
580
  source = { registry = "https://pypi.org/simple" }
581
581
  dependencies = [
582
582
  { name = "jmespath" },
583
583
  { name = "python-dateutil" },
584
584
  { name = "urllib3" },
585
585
  ]
586
- sdist = { url = "https://files.pythonhosted.org/packages/53/1c/3a75deae60e36bd0ee5c27d040384756b2ea1c90bd7c8c9658335a18b4f5/botocore-1.43.67.tar.gz", hash = "sha256:6fe5cfa0c8676ba809efe505b618ec00f30d1af2d014bf316a7aa4ee86accb20", size = 15889514, upload-time = "2026-08-07T19:30:15.638Z" }
586
+ sdist = { url = "https://files.pythonhosted.org/packages/84/da/726b23443ebc77078387fbf330ef7240bc6a96553e566e45a647cd8f714c/botocore-1.43.69.tar.gz", hash = "sha256:5caa46b740d9a886137146ffbb69edb691f702bfe74c64e85621947ae00181fd", size = 15911844, upload-time = "2026-08-11T19:24:20.778Z" }
587
587
  wheels = [
588
- { url = "https://files.pythonhosted.org/packages/21/be/38af8e96f3d200c9d34eab8e9f69a4468388ed6030ea04ff012974e5af5a/botocore-1.43.67-py3-none-any.whl", hash = "sha256:48ab8e9fac26fbc2a700d57010251003e6a5f731cf74d8540fb796bc8f3fc0ef", size = 15575924, upload-time = "2026-08-07T19:30:12.116Z" },
588
+ { url = "https://files.pythonhosted.org/packages/64/ef/a1effbe4ffabadc38ea9425c54601262eaac8cbb5b6089f8f76536d3c8b1/botocore-1.43.69-py3-none-any.whl", hash = "sha256:b1f0e01c53d6b84ee9c184ebf3636c3b3aef85e0ae8498c74afb8734ff224f87", size = 15596589, upload-time = "2026-08-11T19:24:18.283Z" },
589
589
  ]
590
590
 
591
591
  [[package]]
@@ -853,7 +853,7 @@ wheels = [
853
853
 
854
854
  [[package]]
855
855
  name = "classifyre-cli"
856
- version = "0.4.106"
856
+ version = "0.4.108"
857
857
  source = { editable = "." }
858
858
  dependencies = [
859
859
  { name = "beautifulsoup4" },
@@ -1392,7 +1392,7 @@ youtube = [
1392
1392
 
1393
1393
  [[package]]
1394
1394
  name = "classifyre-schemas"
1395
- version = "0.4.106"
1395
+ version = "0.4.108"
1396
1396
  source = { editable = "../../packages/schemas" }
1397
1397
  dependencies = [
1398
1398
  { name = "fastjsonschema" },
@@ -1628,7 +1628,7 @@ wheels = [
1628
1628
 
1629
1629
  [[package]]
1630
1630
  name = "datamodel-code-generator"
1631
- version = "0.72.2"
1631
+ version = "0.72.3"
1632
1632
  source = { registry = "https://pypi.org/simple" }
1633
1633
  dependencies = [
1634
1634
  { name = "argcomplete" },
@@ -1640,9 +1640,9 @@ dependencies = [
1640
1640
  { name = "pydantic" },
1641
1641
  { name = "pyyaml" },
1642
1642
  ]
1643
- sdist = { url = "https://files.pythonhosted.org/packages/b6/2d/12becb81ac1492ed5f6e3afcb2426e0d665c5ae51fa24bbe951b408dd867/datamodel_code_generator-0.72.2.tar.gz", hash = "sha256:0e11564564ccf12e8ae89ca28b7848c795b40609e9f011e7b3434428eebd6f12", size = 1856918, upload-time = "2026-08-06T14:36:05.515Z" }
1643
+ sdist = { url = "https://files.pythonhosted.org/packages/14/4b/4652f0bb085a564982c3e515a0b02bcee21765ddac967bcf152a70d2af14/datamodel_code_generator-0.72.3.tar.gz", hash = "sha256:a20160de09b76d4a293ccba5a9ee5c341b5365890237ac1ff812f420e4c09f3b", size = 1965678, upload-time = "2026-08-10T18:58:41.636Z" }
1644
1644
  wheels = [
1645
- { url = "https://files.pythonhosted.org/packages/da/e5/a64c15b05307974cf9676a73ab9e11bed49656a1df16188685c73cb290ed/datamodel_code_generator-0.72.2-py3-none-any.whl", hash = "sha256:df75b3a3225085e098337538cb6895f12e4daca80c43dc15284102bd42948dfc", size = 514012, upload-time = "2026-08-06T14:36:03.785Z" },
1645
+ { url = "https://files.pythonhosted.org/packages/84/fd/9d8a0594aedcc6ee8133b21dd3543d6021842e013058803a69918720d0aa/datamodel_code_generator-0.72.3-py3-none-any.whl", hash = "sha256:4536f6dd12dd86c9c7a78b16ef83ae9aa7a9cbdb8bef8a3b63baa4ad9d3d3829", size = 554226, upload-time = "2026-08-10T18:58:40.087Z" },
1646
1646
  ]
1647
1647
 
1648
1648
  [[package]]
@@ -1825,7 +1825,7 @@ chunking = [
1825
1825
 
1826
1826
  [[package]]
1827
1827
  name = "docling-ibm-models"
1828
- version = "3.13.3"
1828
+ version = "3.14.0"
1829
1829
  source = { registry = "https://pypi.org/simple" }
1830
1830
  dependencies = [
1831
1831
  { name = "accelerate" },
@@ -1845,14 +1845,14 @@ dependencies = [
1845
1845
  { name = "transformers", version = "5.8.1", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform == 'darwin'" },
1846
1846
  { name = "transformers", version = "5.15.0", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform != 'darwin'" },
1847
1847
  ]
1848
- sdist = { url = "https://files.pythonhosted.org/packages/37/2b/c0ad433da1210672d6e8e774f1ba601824e0d23153e8cd963521dcf1c28c/docling_ibm_models-3.13.3.tar.gz", hash = "sha256:8c8b55e80b3d20fc74d85ca49a4d064578ef75b9f7251eec42fc9df6af426218", size = 98768, upload-time = "2026-06-04T08:23:08.088Z" }
1848
+ sdist = { url = "https://files.pythonhosted.org/packages/bd/b5/f95bd7df8acc3b792fd11c6d00c8a9ea3966b10edd734fb194d07be29606/docling_ibm_models-3.14.0.tar.gz", hash = "sha256:def964e3d524f66c7321ef9d48d4021278f14319f01d3f78058cd2324f641e22", size = 100765, upload-time = "2026-08-11T06:58:25.953Z" }
1849
1849
  wheels = [
1850
- { url = "https://files.pythonhosted.org/packages/1b/6e/a3acfc130967e44e7e3d185c7f59f5ae96df955647e87be533f20576ac41/docling_ibm_models-3.13.3-py3-none-any.whl", hash = "sha256:50fc83d244ce2dc43158e02155d1caa68374d7a169d0f34e67d7eb14f396ffe6", size = 94040, upload-time = "2026-06-04T08:23:06.893Z" },
1850
+ { url = "https://files.pythonhosted.org/packages/4e/96/c168e6d31397203eeed572c3b2cd1bb1efff7f9b0753cb53855fd505894a/docling_ibm_models-3.14.0-py3-none-any.whl", hash = "sha256:795d39cd0f7b1e14a702e681b0ef0f9bd31deaedddb4e2686ad577296ecb8fc9", size = 94362, upload-time = "2026-08-11T06:58:24.513Z" },
1851
1851
  ]
1852
1852
 
1853
1853
  [[package]]
1854
1854
  name = "docling-parse"
1855
- version = "7.11.0"
1855
+ version = "7.12.0"
1856
1856
  source = { registry = "https://pypi.org/simple" }
1857
1857
  dependencies = [
1858
1858
  { name = "docling-core" },
@@ -1860,23 +1860,23 @@ dependencies = [
1860
1860
  { name = "pydantic" },
1861
1861
  { name = "pywin32", marker = "sys_platform == 'win32'" },
1862
1862
  ]
1863
- sdist = { url = "https://files.pythonhosted.org/packages/73/47/262fa6a749e23f5690cf3573e5ef8fd471eb6c0b0b2115cfd4106952c4ea/docling_parse-7.11.0.tar.gz", hash = "sha256:1b547372e3cdbf62d0c989a9717f4dfeaf1c12722c128e30cf6b1f57b1e6a2e4", size = 6823554, upload-time = "2026-08-07T12:14:33.047Z" }
1863
+ sdist = { url = "https://files.pythonhosted.org/packages/98/bf/e2e75880a275d02016536a4969edf6827f12f6a8f9e3733e162647330021/docling_parse-7.12.0.tar.gz", hash = "sha256:62e07e64d0f1ec7e8dd69a0fe9c5dc1d3c6566e4215db3200254bb91c0950fb0", size = 6826844, upload-time = "2026-08-11T09:37:26.692Z" }
1864
1864
  wheels = [
1865
- { url = "https://files.pythonhosted.org/packages/03/6d/6ba5860d90e50cdea28b9f5390fa5a195fa7e9877675f11f13c42e72b8e2/docling_parse-7.11.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:d2f167f7c474c02e09059c752ed38f54e1978a1d22ca08f319990c6ba18d4844", size = 9666019, upload-time = "2026-08-07T12:13:48.863Z" },
1866
- { url = "https://files.pythonhosted.org/packages/62/66/d03f305c1bd8543495c26b5e84dc8a0410271b41cf8f2edec466f6da52f2/docling_parse-7.11.0-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:341d197047355af7cf9ce66a1d01d2a0504c335d9409b405cfeea8359fafc23b", size = 10389559, upload-time = "2026-08-07T12:13:51.474Z" },
1867
- { url = "https://files.pythonhosted.org/packages/e3/fe/d2e75bc1eaed77c9d99ada781f34344b29e56337ff28f22b17902150829e/docling_parse-7.11.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8d3e3e81de3693a9d1b619cb6e3919acfc74292d40a9e2a62b46bfa1a2f1443", size = 10811073, upload-time = "2026-08-07T12:13:54.151Z" },
1868
- { url = "https://files.pythonhosted.org/packages/dc/63/283b5d41858ade971182e4a88250bc72523a46305a3202e2db7f0b3e488a/docling_parse-7.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:c703e0220d9c5fcbfd85e7db4419e2d55d4af076c12237268aff29ec2d1a8b50", size = 11566995, upload-time = "2026-08-07T12:14:00.662Z" },
1869
- { url = "https://files.pythonhosted.org/packages/da/19/b6015489d1ee6256045928a458bb8f5b3b4a94e4a19be2141db26427223f/docling_parse-7.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:09c2deb1d401fd46bba9a18f8746babb068a9a8da7e566ca2a9a935bd28d0c1c", size = 8953897, upload-time = "2026-08-07T12:14:03.066Z" },
1870
- { url = "https://files.pythonhosted.org/packages/c6/84/614a3b6b4c0263fc8d06a24ae03fe75d438c431bc525b4b71ce7a011923a/docling_parse-7.11.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:4a339f8e6a15bf13359359d2ad236b4bb1c6bf51d606ba4ce03cbaeddc60d579", size = 9665921, upload-time = "2026-08-07T12:14:05.596Z" },
1871
- { url = "https://files.pythonhosted.org/packages/b7/47/9c3e0232ddeb198c07eca3bdea9b502ff46e9372e92f010594cb63875e2c/docling_parse-7.11.0-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f1b93fb9f21832fb7f68e7f9220f34ffe3ec14591783fc29c91374bdf0e8ddd3", size = 10389996, upload-time = "2026-08-07T12:14:08.209Z" },
1872
- { url = "https://files.pythonhosted.org/packages/61/0e/0bc5b01967ad16c88766ffc72ac42e6deeeb160e734f1b7f383c746a082a/docling_parse-7.11.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:94faec9b76e8c65c7e5aeeb20004aa9703fb78c3cf52bac2ee8dd155569f22e7", size = 10810601, upload-time = "2026-08-07T12:14:10.922Z" },
1873
- { url = "https://files.pythonhosted.org/packages/aa/53/9492e1c5a8065df32e0006b269ec384cb47da0fcc2e1a081329ddba03712/docling_parse-7.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:17313f4d3a8df8591e395ba2eef3683bb93155ffccdd07672958854d6b6c4325", size = 11566813, upload-time = "2026-08-07T12:14:13.755Z" },
1874
- { url = "https://files.pythonhosted.org/packages/16/4c/7e7d5681cbd0583aa63da04d7691dddfc08606b1796703ba90a8abc56282/docling_parse-7.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:1933c9c15da56d61bb446d9d9308cd11a090ffd9a51a23a509abbc6e013bdb09", size = 8953953, upload-time = "2026-08-07T12:14:16.412Z" },
1875
- { url = "https://files.pythonhosted.org/packages/59/b3/d6ace3a5ddf49bd690495bf6b3cb7dd26bfc4aa5c89554895ff5f349c95e/docling_parse-7.11.0-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:e6a7b1b0cf2b0c08100ae8a816645f7ca2982faef87497bc4ae61c888c8d0beb", size = 9667615, upload-time = "2026-08-07T12:14:19.079Z" },
1876
- { url = "https://files.pythonhosted.org/packages/96/8b/363fa887afbda74f1959c17a404d7b16b53376538268387c5e4b886fbe11/docling_parse-7.11.0-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5ad269b2bf35913646e768691be765ec2d5d95feee59ffbeff16339ee188cbef", size = 10390002, upload-time = "2026-08-07T12:14:21.929Z" },
1877
- { url = "https://files.pythonhosted.org/packages/a1/87/0551bfe3218c716e862ec06ec958f285fdc472869ce4b2a3e60407d7d92c/docling_parse-7.11.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6a8c65959bd865ce070ebc6b1e6b5ae6c3ad267456beb94cbad9ae18dc5f7387", size = 10810617, upload-time = "2026-08-07T12:14:24.701Z" },
1878
- { url = "https://files.pythonhosted.org/packages/e6/43/cb89fc9509fa922ce9b1bb6edfd94d9015f1b434944070b6a1d7119236ac/docling_parse-7.11.0-cp314-cp314-win_amd64.whl", hash = "sha256:d75adcc671b038f4b2ebb7d51785c0d536ce8894c300aebecd410342c92a9a1d", size = 11995648, upload-time = "2026-08-07T12:14:27.567Z" },
1879
- { url = "https://files.pythonhosted.org/packages/1a/89/9f2251c489a8350c19823ee7457d400aea1812dcc51e3ce17666e8c8e485/docling_parse-7.11.0-cp314-cp314-win_arm64.whl", hash = "sha256:8433396d8ea61f4d0d1de246e6a9b713940ddc1e1e2f2230582a771508caa56c", size = 9319396, upload-time = "2026-08-07T12:14:30.474Z" },
1865
+ { url = "https://files.pythonhosted.org/packages/23/93/d816fa83c06a12d636f41101a97d317c670386be46b3c98c6fad96165771/docling_parse-7.12.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:aaeda6aeef6d18de3931c118c8c2738d4d96d0bc905a1d35c08f5efca7f7bf32", size = 9656222, upload-time = "2026-08-11T09:36:56.661Z" },
1866
+ { url = "https://files.pythonhosted.org/packages/53/1f/118c2449d9010fdd1f9d3ece848bd654261207127e4eca1c058ae756ff28/docling_parse-7.12.0-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9a46b8d7b24d8739398c15ebc99020f8d1aba39bfe29b0228277718bbe720433", size = 10177571, upload-time = "2026-08-11T09:36:58.53Z" },
1867
+ { url = "https://files.pythonhosted.org/packages/d5/10/da10719d994196050342ac4677f586baf77a3f8f8525016c2b94a43a238a/docling_parse-7.12.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1782df91ffa439518c56d745ba9f6bcf6b899c3fd9942331c7e0f4a99aefd2e9", size = 10562851, upload-time = "2026-08-11T09:37:00.786Z" },
1868
+ { url = "https://files.pythonhosted.org/packages/97/62/33d690f2af829233ab8e7ed8509bd003116a1f6debf13bc7bfed64fff748/docling_parse-7.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:871210fe8554a0f8b55a04de563d61183fa8b40e4e809c19b5f969c7b4f019de", size = 11623243, upload-time = "2026-08-11T09:37:02.891Z" },
1869
+ { url = "https://files.pythonhosted.org/packages/7c/77/ec04cc06b5d6e026dcd7ca05293ef2687839351f566dc040c865e0da7e92/docling_parse-7.12.0-cp312-cp312-win_arm64.whl", hash = "sha256:ad24c38f46dc99d96864bdb88a48769bb71697cad96ea20e4d2f48cad42d4977", size = 8950994, upload-time = "2026-08-11T09:37:04.912Z" },
1870
+ { url = "https://files.pythonhosted.org/packages/1e/c4/d544a97dc93db0932dd52a8fe9941ca2b59bef1333c8f398cb3f2232bae8/docling_parse-7.12.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:dcef3d25258750c02326bfb7899b753366bda1543fd58e6a8329bc2d7344b3f7", size = 9656250, upload-time = "2026-08-11T09:37:06.602Z" },
1871
+ { url = "https://files.pythonhosted.org/packages/bf/ff/2f4607d9e3b93a9321f6ad2de2379b829a975bd9153ed4009dc83467db99/docling_parse-7.12.0-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f5cb24e4806191ff063bb17b08931f8043c8905c707d19004b1f684734b99392", size = 10177684, upload-time = "2026-08-11T09:37:08.634Z" },
1872
+ { url = "https://files.pythonhosted.org/packages/5d/50/d43a896ade40afd97b2fbcc17169bdc4abcbc442310114df66eaa2555c02/docling_parse-7.12.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:60fd9d4fe416335c1f241ea5fa697a6d361022fe4c285f3535c594dcbc2005ad", size = 10562643, upload-time = "2026-08-11T09:37:10.746Z" },
1873
+ { url = "https://files.pythonhosted.org/packages/d0/28/ca952f6c5aff3e7650498e1ceedac070ab56d44a0799256b7dc2be316185/docling_parse-7.12.0-cp313-cp313-win_amd64.whl", hash = "sha256:5944d21942d0dd22438fd3edc97343665ad44b92d5208b7683bd6af0bd7ed20f", size = 11622973, upload-time = "2026-08-11T09:37:12.709Z" },
1874
+ { url = "https://files.pythonhosted.org/packages/09/43/e84d09f86a40d288296fe9413429c4bcda64991da52f16283a868493e247/docling_parse-7.12.0-cp313-cp313-win_arm64.whl", hash = "sha256:58e4e1830af45933ff58762c8a22c47d7448ccc3a43eb9d4d567822a613403a6", size = 8950908, upload-time = "2026-08-11T09:37:14.815Z" },
1875
+ { url = "https://files.pythonhosted.org/packages/fc/75/976c9a5788d17024e27bc9ebd7547b6286b0411b1f0422e0eb2728eea48a/docling_parse-7.12.0-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:00dec572aec9b2f64aee7e724f236f05a83065cbe464145667e64d1d68d1cc2f", size = 9656572, upload-time = "2026-08-11T09:37:16.664Z" },
1876
+ { url = "https://files.pythonhosted.org/packages/aa/ef/9914e74ebbd538a20a178fd29d7d7eaef3ea0c981975844a854aaa79d732/docling_parse-7.12.0-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbd42aba4ac361bf4e8b9e8bdf8be8516fc8030510c4360435790045af0ec337", size = 10178399, upload-time = "2026-08-11T09:37:18.384Z" },
1877
+ { url = "https://files.pythonhosted.org/packages/99/9b/642de8e568ce1aec65d53bb438d0a98583052d915d8bbedd0a840b76a9f5/docling_parse-7.12.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd62f8ac2a5403f427ac0d49aaf8f4f369219f24d6f0005175510ec5e9f40b33", size = 10563406, upload-time = "2026-08-11T09:37:20.359Z" },
1878
+ { url = "https://files.pythonhosted.org/packages/fe/c8/4a741e56c9851d7283771b9206a517e598ffdcfff6366d1f1f5e43f6924d/docling_parse-7.12.0-cp314-cp314-win_amd64.whl", hash = "sha256:2dcb6f4c231066e87aafd7d90c492d634db27851e470042a57c22764bf6ca8aa", size = 12055028, upload-time = "2026-08-11T09:37:22.483Z" },
1879
+ { url = "https://files.pythonhosted.org/packages/6c/00/d2ff3db1f562c8a4acff7e766da3726285b9a2767e0b6c356e94f0563fd5/docling_parse-7.12.0-cp314-cp314-win_arm64.whl", hash = "sha256:882d4904f6c7889a8256213e882fe41a5b1b3fb3d1d044c162cfffa019a2e42e", size = 9316100, upload-time = "2026-08-11T09:37:24.354Z" },
1880
1880
  ]
1881
1881
 
1882
1882
  [[package]]
@@ -2947,7 +2947,7 @@ wheels = [
2947
2947
 
2948
2948
  [[package]]
2949
2949
  name = "litellm"
2950
- version = "1.96.0"
2950
+ version = "1.96.2"
2951
2951
  source = { registry = "https://pypi.org/simple" }
2952
2952
  dependencies = [
2953
2953
  { name = "aiohttp" },
@@ -2964,29 +2964,15 @@ dependencies = [
2964
2964
  { name = "tiktoken" },
2965
2965
  { name = "tokenizers" },
2966
2966
  ]
2967
- sdist = { url = "https://files.pythonhosted.org/packages/d0/92/1171e76f2a4204a65adb5c827475e4f1d30e7c6a89d3d3e944d58b6fd8a6/litellm-1.96.0.tar.gz", hash = "sha256:340a9b04e1bf8486b0b99f3f6a5556aa59c8f9c16b11b362c95eabea1bcf7a9d", size = 17679976, upload-time = "2026-08-09T01:36:56.266Z" }
2968
- wheels = [
2969
- { url = "https://files.pythonhosted.org/packages/14/7b/706a7176b1d38529b62724f97e75c98facecc1ac6a60a196c589f5b84aca/litellm-1.96.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:518b9b71a4d7582a0f54f93a65ae4f715ba41bc4475f4a2b9096742612f05f4d", size = 25932809, upload-time = "2026-08-09T01:35:57.551Z" },
2970
- { url = "https://files.pythonhosted.org/packages/57/25/ad9b206ad7170018d95bf4fc777c492921d69c3f6d99e8c396612f23dee8/litellm-1.96.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:05da78216567c1b0d288ce17a9650d1b4a45b8b06fe23384b2fc5835a375a8fb", size = 25643217, upload-time = "2026-08-09T01:36:01.186Z" },
2971
- { url = "https://files.pythonhosted.org/packages/11/a2/5f2a03b19d7718e1d01c2c5a764dece7f768e8e7ea08a8412f130e166af8/litellm-1.96.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:61b2b93a24a1733bc718c2255f5c8cf84fb8ef60ab87f544494dd3386b2be04c", size = 26579330, upload-time = "2026-08-09T01:36:04.114Z" },
2972
- { url = "https://files.pythonhosted.org/packages/78/86/9a6480a10edff9c772c03d718d50bb4bdea25f5a94ffc3aa623a199f506c/litellm-1.96.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:2e72181f99794d5b6ac01ee18b97a31b7eee93321c9e5b5e5caa36d062822fc0", size = 26443987, upload-time = "2026-08-09T01:36:06.557Z" },
2973
- { url = "https://files.pythonhosted.org/packages/4d/bb/1c08d953f69f977f5d17e0912d9847512a80ecb43b4d5f235ae61610917f/litellm-1.96.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:66b97502d727259f29c486da38921b698a8c816d9eef7d4706a686c63436387a", size = 26653427, upload-time = "2026-08-09T01:36:09.542Z" },
2974
- { url = "https://files.pythonhosted.org/packages/72/77/64ee801331b13bc138de73b216e031dd90e0b6f9a1ae24d33c134d830227/litellm-1.96.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0fdd57b61b6cdf0562eb6daec1d7f02a57dec34ba8f33cd3080bfb5e1beba02b", size = 26860925, upload-time = "2026-08-09T01:36:12.231Z" },
2975
- { url = "https://files.pythonhosted.org/packages/8f/54/6f8395af7b1ebc7b16251cfd521f780fe4826dc634a6947d08f50f3a75f8/litellm-1.96.0-cp312-cp312-win_amd64.whl", hash = "sha256:4d4f454a86736915762ad8e67817992f7e3f1c7aed2b42be32ace4e4ecd1d20c", size = 25054400, upload-time = "2026-08-09T01:36:14.9Z" },
2976
- { url = "https://files.pythonhosted.org/packages/2b/1e/ac71d20d3c5df942d8877b834e5db190b77395317f436e59c77e5c8b0ef3/litellm-1.96.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:baf13fd3176a569b2924e2c4bb4e82da03a11e1a7cf4144ea2d92a1b40d87c17", size = 25933352, upload-time = "2026-08-09T01:36:17.98Z" },
2977
- { url = "https://files.pythonhosted.org/packages/ed/1e/76c666f9ba4e0a20d8b3fca8f0af369f97d2e2c2a4874b10b4f344c6bed7/litellm-1.96.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:26d2ae2a5f8a839b757cfb7744ffa0c95f225c583984b99352887fcf4e5456ef", size = 25643356, upload-time = "2026-08-09T01:36:20.535Z" },
2978
- { url = "https://files.pythonhosted.org/packages/56/fc/48cdbdb1fc6d0ec573bb9b1c04fe81528d84886e1cde0100d4c38e0238f1/litellm-1.96.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:887fd96224c2197897b1df309e9e8d984196a3d18472f908a6aa5a371e569b25", size = 26580407, upload-time = "2026-08-09T01:36:23.345Z" },
2979
- { url = "https://files.pythonhosted.org/packages/cc/48/c1bddb7e7c328816a0136d94afa455279b825d13e1507b669da2e2be78b8/litellm-1.96.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:1a75d7718fc72e526501d568c01f50278206106d1db7d77e6c34973e0877a77f", size = 26444531, upload-time = "2026-08-09T01:36:26.24Z" },
2980
- { url = "https://files.pythonhosted.org/packages/c7/63/0f4109c7e19bb78735e87f9fcca565750d49a71b022941ba89366f764cd5/litellm-1.96.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:217191eeb91561372e1f079f2925a15753f1c41955256e09e11787d7c1dca94b", size = 26653932, upload-time = "2026-08-09T01:36:28.81Z" },
2981
- { url = "https://files.pythonhosted.org/packages/65/9e/812d87aee7db46f9cde44ce96aec25de90f1c4f356def2bb7f6d1ec0a011/litellm-1.96.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b1cc10ba307cb31e9a799bfcdcfed4cb0a558c5cfb867a970cc6159d6ec649bc", size = 26861204, upload-time = "2026-08-09T01:36:31.467Z" },
2982
- { url = "https://files.pythonhosted.org/packages/61/80/0d276c052f54386a491571792818d7e24e3bcf2a1fae45f431cdb4b8c15f/litellm-1.96.0-cp313-cp313-win_amd64.whl", hash = "sha256:d64c7746768aa2df6a85d63bb6ea0a092488584131ed5e0d49e52e4088e60d20", size = 25054138, upload-time = "2026-08-09T01:36:34.391Z" },
2983
- { url = "https://files.pythonhosted.org/packages/1c/05/96a800df42d6734f912786d99e77e573f5360ba08f7a68292d067cc291cd/litellm-1.96.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:7a86e14eb6c275f8588f3d364d91cbd935f5eebada28593a08b9106f68bc7681", size = 25935008, upload-time = "2026-08-09T01:36:37.043Z" },
2984
- { url = "https://files.pythonhosted.org/packages/42/8f/bff76ef3d44863d0ace55c3ed01e18a481cc93c2fc4a7c6837e6f6655482/litellm-1.96.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e3c39a0313aadbd771439e9c31b0878eb04992ce29b1b51d0003eccd91feb71d", size = 25643765, upload-time = "2026-08-09T01:36:39.721Z" },
2985
- { url = "https://files.pythonhosted.org/packages/d0/4f/215578f922c301643852309d82b459d699e6a86aae1872fde60c4e33366a/litellm-1.96.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:10c8f4dcf50ba88e3958f0d2c4483f0934622c03b1c5adce14e57d7fd597f3d3", size = 26578304, upload-time = "2026-08-09T01:36:42.887Z" },
2986
- { url = "https://files.pythonhosted.org/packages/f8/9c/aa4bf7cc574eac46ec22d80a9e4c895fa438b3b32c54465a092b2b90714b/litellm-1.96.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:63f98de57415d8f96f3f07d011b11947d3358b5934a66676ae7ec98244613f08", size = 26444536, upload-time = "2026-08-09T01:36:45.408Z" },
2987
- { url = "https://files.pythonhosted.org/packages/34/09/62bb156ffb051bb4ed28a14549c649147d8e231cbef9bad5935aa9a8ae02/litellm-1.96.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0b03e44a3cd0c03421e5afc024e4d6c88ed6f7ed51b7b566cc4eb41652fa629a", size = 26650611, upload-time = "2026-08-09T01:36:48.047Z" },
2988
- { url = "https://files.pythonhosted.org/packages/86/7b/3f5ed4d2a5e23aee7c130fca3a6f81bf1c305922e16135f2c476ee8747f0/litellm-1.96.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:340f893e9bfc4bd283565a7fe9f159840c8641763d533d381580359bfbfc4fe8", size = 26861612, upload-time = "2026-08-09T01:36:51.017Z" },
2989
- { url = "https://files.pythonhosted.org/packages/1a/17/3ec96e43009c91c7cec8ddf6dc830ce2dd03a3f7c5f853267f894daf44ed/litellm-1.96.0-cp314-cp314-win_amd64.whl", hash = "sha256:7ba695d5ea090923fa2338b20c249a504e19bb492d1e61a5a55235c9e8b49931", size = 25056208, upload-time = "2026-08-09T01:36:53.744Z" },
2967
+ sdist = { url = "https://files.pythonhosted.org/packages/79/fe/d03be8a6be6914fabacef29457a2b3d02128c52c448cc6f3019b8e63488b/litellm-1.96.2.tar.gz", hash = "sha256:80d477ae092b05ce023b5084542cb3cb75999b52b1dd2e4d834fb348effc9399", size = 17682558, upload-time = "2026-08-11T21:12:24.117Z" }
2968
+ wheels = [
2969
+ { url = "https://files.pythonhosted.org/packages/46/85/653d0095a163cc9a1f2f1aa629cf4493c57c3abe13bd806290fc5d57458b/litellm-1.96.2-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:0aa667c6fc58b20ff04fe5efaac5cf48b1e224bac32dbf22ced2e5ee695bc4ba", size = 24102871, upload-time = "2026-08-11T21:12:06.152Z" },
2970
+ { url = "https://files.pythonhosted.org/packages/29/a1/1322630271fbb291e97b54eb46baa8c4f512130a620a8428c7460b4ef414/litellm-1.96.2-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:e5d96d16b37a043e482a134a71b0c1df4e700603fc14df22e4bd27dc9e38f5c4", size = 23760722, upload-time = "2026-08-11T21:12:09.257Z" },
2971
+ { url = "https://files.pythonhosted.org/packages/17/0e/e0e2734194072a438298e94dbc3c37879d335fdf50881ce8995daa6878d1/litellm-1.96.2-cp310-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:1a42d68b903f6b605bd7744e9700b16a725f897c5edcc448e491cec14cd5a9db", size = 23898969, upload-time = "2026-08-11T21:12:11.68Z" },
2972
+ { url = "https://files.pythonhosted.org/packages/b5/84/993c40c116c699383741fd27da515c71b395609859148ea32720925eaeaf/litellm-1.96.2-cp310-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:76e9c72cb6757bb7c35cd23e3e4fc028910795910ae92491076bd50f7b61f205", size = 24264588, upload-time = "2026-08-11T21:12:14.18Z" },
2973
+ { url = "https://files.pythonhosted.org/packages/d8/02/21dc260ae3fd72b23544abce23ad5f3d563e3d39a4f617bba6d98f4b9c31/litellm-1.96.2-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1f304b8854e385946469d2dcf8ef88e24357120671caeaddea11b085b0302308", size = 23973160, upload-time = "2026-08-11T21:12:16.616Z" },
2974
+ { url = "https://files.pythonhosted.org/packages/64/5d/e79f86b43f07aff7f796faf3c6d1025f6ab9da43f72b7c555a26811af191/litellm-1.96.2-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:8c21a57a0f3507176492a4f65361a4302af1a0723c97e96961c7ed0e96934832", size = 24360615, upload-time = "2026-08-11T21:12:18.947Z" },
2975
+ { url = "https://files.pythonhosted.org/packages/3e/6a/c2e3058fd3766eebe5685c688d9e85adb9749e946580f46214a651661522/litellm-1.96.2-cp310-abi3-win_amd64.whl", hash = "sha256:0168e49cffecb0b45a0d044ecb7e5f7f6fc9e14d974b50f54edfa9d8e0db9c1d", size = 24154302, upload-time = "2026-08-11T21:12:21.221Z" },
2990
2976
  ]
2991
2977
 
2992
2978
  [[package]]
@@ -3111,11 +3097,11 @@ wheels = [
3111
3097
 
3112
3098
  [[package]]
3113
3099
  name = "mail-parser"
3114
- version = "4.6.0"
3100
+ version = "4.6.1"
3115
3101
  source = { registry = "https://pypi.org/simple" }
3116
- sdist = { url = "https://files.pythonhosted.org/packages/4e/62/54e04e45102517d564142e1cc3e0fa4a9a9db32f1c5dd2aff82b02f47220/mail_parser-4.6.0.tar.gz", hash = "sha256:d4251ff1eef58bf2ed2d39007e83762e8edd6be2df01334ff24aad9c1a75605d", size = 2859373, upload-time = "2026-08-09T08:44:29.811Z" }
3102
+ sdist = { url = "https://files.pythonhosted.org/packages/0e/43/82f02f29f2091e426b609e42ff2b0c9da32dc78c32ddd2c3cde61bc947b6/mail_parser-4.6.1.tar.gz", hash = "sha256:7381853eccb551c83090c90f3ef16e433e8c9b320acbe27145a13c0d2fca480f", size = 2869128, upload-time = "2026-08-12T07:25:00.912Z" }
3117
3103
  wheels = [
3118
- { url = "https://files.pythonhosted.org/packages/b1/7c/d30573d54c9ae44945feca9085125c307748f9a7727e053bac9ffab708fc/mail_parser-4.6.0-py3-none-any.whl", hash = "sha256:18f02d80d2e561c992514d1cc602b98a6a2c3fa5911c415bb291492cc43826e7", size = 36979, upload-time = "2026-08-09T08:44:28.463Z" },
3104
+ { url = "https://files.pythonhosted.org/packages/e6/02/bd1768a316a302c622913c4ffd37f9aa660f0a5907f5d2c4b151f9352871/mail_parser-4.6.1-py3-none-any.whl", hash = "sha256:f688394e26e3f838fee33039bda5b8ea1876622c81ff0c5f0db5a817379ff62c", size = 39279, upload-time = "2026-08-12T07:24:59.797Z" },
3119
3105
  ]
3120
3106
 
3121
3107
  [[package]]
@@ -3132,11 +3118,11 @@ wheels = [
3132
3118
 
3133
3119
  [[package]]
3134
3120
  name = "marko"
3135
- version = "2.2.3"
3121
+ version = "2.2.4"
3136
3122
  source = { registry = "https://pypi.org/simple" }
3137
- sdist = { url = "https://files.pythonhosted.org/packages/58/cc/01b80dc58e4d44fe039403ef1ac0008bcb9375364ccd246a4b8bfec29b46/marko-2.2.3.tar.gz", hash = "sha256:e31ec2875383bc62f9093d16babed5a2c2cde601c00d834ea935a2222120ec19", size = 144531, upload-time = "2026-05-28T02:07:39.479Z" }
3123
+ sdist = { url = "https://files.pythonhosted.org/packages/82/6d/671a18bb386adca6311bca6c2fe6bec873947ee501cc5f8f509ec06bdde0/marko-2.2.4.tar.gz", hash = "sha256:c042c66f835425673123d7536b39b4660de3b68e30078c70fd26245b31170683", size = 151013, upload-time = "2026-08-12T03:20:11.772Z" }
3138
3124
  wheels = [
3139
- { url = "https://files.pythonhosted.org/packages/97/50/0a8fab45fa374820c27cc4c3178c4914c60902ba9d6404a692a979e20dbc/marko-2.2.3-py3-none-any.whl", hash = "sha256:8e1d7a0387281e59dfbc52a381b58c570156970e36b2bbe047f8a3a2f368cacc", size = 42951, upload-time = "2026-05-28T02:07:38.373Z" },
3125
+ { url = "https://files.pythonhosted.org/packages/d3/78/751d49c8bdfa0b30147c99235516433af6b63eca367ff28593c7346a0494/marko-2.2.4-py3-none-any.whl", hash = "sha256:d80510506edba096ec49d4720a09645fa0bb78e7b7b88697f20032fc19730aa9", size = 46753, upload-time = "2026-08-12T03:20:10.811Z" },
3140
3126
  ]
3141
3127
 
3142
3128
  [[package]]
@@ -3906,7 +3892,7 @@ wheels = [
3906
3892
 
3907
3893
  [[package]]
3908
3894
  name = "openai"
3909
- version = "2.53.0"
3895
+ version = "2.54.0"
3910
3896
  source = { registry = "https://pypi.org/simple" }
3911
3897
  dependencies = [
3912
3898
  { name = "anyio" },
@@ -3918,9 +3904,9 @@ dependencies = [
3918
3904
  { name = "tqdm" },
3919
3905
  { name = "typing-extensions" },
3920
3906
  ]
3921
- sdist = { url = "https://files.pythonhosted.org/packages/ef/cf/36e3e7235fdf6d125c052acc0970924611b17a20a4fe580596faf4566a65/openai-2.53.0.tar.gz", hash = "sha256:baf5802ad08980e1d9d561e1b996e800c8bcd14af5847c6d0e7a5cc59e4d4116", size = 1099435, upload-time = "2026-08-03T21:42:01.664Z" }
3907
+ sdist = { url = "https://files.pythonhosted.org/packages/50/9a/8c75e8c8a5b407a0586faeb2afac91674ff955c191ecc1d6d3b6669f6788/openai-2.54.0.tar.gz", hash = "sha256:e3e6f8bc1ba30ddf381ace1a14340eed381cb984a1a59bd0f34b5be3b5d49cfa", size = 1100285, upload-time = "2026-08-11T18:46:59.035Z" }
3922
3908
  wheels = [
3923
- { url = "https://files.pythonhosted.org/packages/78/0f/cc6afea3542a5142c5d8fc8211c5e059a8375105d004a41dfa2c7948dbb0/openai-2.53.0-py3-none-any.whl", hash = "sha256:c694ffc747a3c4d1663ef2b07b811315a476164ee5efa3a993967349ebca7618", size = 1659829, upload-time = "2026-08-03T21:41:59.581Z" },
3909
+ { url = "https://files.pythonhosted.org/packages/64/a8/bb76c7356de8ad57f59d5ff993d434df0607f07f08bcc9c9a5c275e399c0/openai-2.54.0-py3-none-any.whl", hash = "sha256:89089789197ccdb87f173a03145ed1598d00795220c93e96cf712b1cbf5e5f2b", size = 1660351, upload-time = "2026-08-11T18:46:56.684Z" },
3924
3910
  ]
3925
3911
 
3926
3912
  [[package]]
@@ -1,3 +0,0 @@
1
- $ uv sync
2
- Resolved 309 packages in 219ms
3
- Checked 51 packages in 1ms
@@ -1,36 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from unittest.mock import AsyncMock
4
-
5
- import pytest
6
-
7
- from src.main import _emit_text_chunks_with_retry
8
-
9
-
10
- @pytest.mark.asyncio
11
- async def test_emit_text_chunks_retries_before_succeeding(
12
- monkeypatch: pytest.MonkeyPatch,
13
- ) -> None:
14
- sink = type("Sink", (), {})()
15
- sink.emit_text_chunks = AsyncMock(side_effect=[RuntimeError("temporary outage"), None])
16
- sleep = AsyncMock()
17
- monkeypatch.setattr("src.main.asyncio.sleep", sleep)
18
-
19
- await _emit_text_chunks_with_retry(sink, "asset-1", object(), attempts=3)
20
-
21
- assert sink.emit_text_chunks.await_count == 2
22
- sleep.assert_awaited_once_with(0.25)
23
-
24
-
25
- @pytest.mark.asyncio
26
- async def test_emit_text_chunks_propagates_exhausted_retries(
27
- monkeypatch: pytest.MonkeyPatch,
28
- ) -> None:
29
- sink = type("Sink", (), {})()
30
- sink.emit_text_chunks = AsyncMock(side_effect=RuntimeError("API unavailable"))
31
- monkeypatch.setattr("src.main.asyncio.sleep", AsyncMock())
32
-
33
- with pytest.raises(RuntimeError, match="API unavailable"):
34
- await _emit_text_chunks_with_retry(sink, "asset-1", object(), attempts=3)
35
-
36
- assert sink.emit_text_chunks.await_count == 3