dreadnode 2.0.3__tar.gz → 2.0.5__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 (417) hide show
  1. {dreadnode-2.0.3 → dreadnode-2.0.5}/PKG-INFO +2 -2
  2. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/agents/events.py +14 -6
  3. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/cli/task.py +3 -0
  4. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/main.py +61 -9
  5. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/server/app.py +53 -2
  6. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/app.py +173 -26
  7. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/client.py +22 -7
  8. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/dreadnode.tcss +35 -15
  9. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/event_contract.py +6 -0
  10. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/model_variants.py +10 -6
  11. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/screens/auth.py +38 -33
  12. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/screens/capabilities.py +22 -2
  13. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/theme.py +21 -20
  14. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/turn_reducer.py +4 -0
  15. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/widgets/conversation.py +6 -5
  16. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/widgets/skills_dialog.py +3 -3
  17. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/widgets/slash_overlay.py +15 -6
  18. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/widgets/tool_progress.py +33 -11
  19. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/widgets/welcome.py +6 -2
  20. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/packaging/task_validation.py +30 -27
  21. {dreadnode-2.0.3 → dreadnode-2.0.5}/pyproject.toml +2 -2
  22. {dreadnode-2.0.3 → dreadnode-2.0.5}/.gitignore +0 -0
  23. {dreadnode-2.0.3 → dreadnode-2.0.5}/LICENSE +0 -0
  24. {dreadnode-2.0.3 → dreadnode-2.0.5}/README.md +0 -0
  25. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/__init__.py +0 -0
  26. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/__main__.py +0 -0
  27. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/agents/__init__.py +0 -0
  28. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/agents/agent.py +0 -0
  29. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/agents/exceptions.py +0 -0
  30. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/agents/format.py +0 -0
  31. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/agents/hooks.py +0 -0
  32. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/agents/mcp/__init__.py +0 -0
  33. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/agents/mcp/auth.py +0 -0
  34. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/agents/mcp/client.py +0 -0
  35. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/agents/mcp/config.py +0 -0
  36. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/agents/mcp/server.py +0 -0
  37. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/agents/reactions.py +0 -0
  38. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/agents/skills.py +0 -0
  39. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/agents/stopping.py +0 -0
  40. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/agents/subagent.py +0 -0
  41. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/agents/tools.py +0 -0
  42. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/agents/trajectory.py +0 -0
  43. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/__init__.py +0 -0
  44. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/analytics/__init__.py +0 -0
  45. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/analytics/aggregator.py +0 -0
  46. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/analytics/classifier.py +0 -0
  47. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/analytics/compliance.py +0 -0
  48. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/analytics/engine.py +0 -0
  49. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/analytics/recommendations.py +0 -0
  50. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/analytics/types.py +0 -0
  51. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/assessment.py +0 -0
  52. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/autodan_turbo.py +0 -0
  53. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/beast.py +0 -0
  54. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/compliance/__init__.py +0 -0
  55. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/compliance/atlas.py +0 -0
  56. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/compliance/nist.py +0 -0
  57. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/compliance/owasp.py +0 -0
  58. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/compliance/owasp_agentic.py +0 -0
  59. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/compliance/saif.py +0 -0
  60. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/constants.py +0 -0
  61. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/crescendo.py +0 -0
  62. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/data/__init__.py +0 -0
  63. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/data/assets/audio/adversarial_query.mp3 +0 -0
  64. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/data/assets/image/bomb.jpg +0 -0
  65. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/data/assets/image/meth.png +0 -0
  66. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/data/prompts/adversarial_benchmark_subset.csv +0 -0
  67. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/data/prompts/ai_safety.csv +0 -0
  68. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/data/rubrics/data_exfiltration.yaml +0 -0
  69. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/data/rubrics/goal_hijacking.yaml +0 -0
  70. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/data/rubrics/memory_poisoning.yaml +0 -0
  71. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/data/rubrics/privilege_escalation.yaml +0 -0
  72. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/data/rubrics/rce.yaml +0 -0
  73. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/data/rubrics/scope_creep.yaml +0 -0
  74. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/data/rubrics/tool_chaining.yaml +0 -0
  75. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/data/rubrics/tool_selection_safety.yaml +0 -0
  76. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/data/rubrics/unbounded_agency.yaml +0 -0
  77. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/data/rubrics/web_chatbot_security.yaml +0 -0
  78. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/data/templates/crescendo/variant_1.yaml +0 -0
  79. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/data/templates/crescendo/variant_2.yaml +0 -0
  80. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/data/templates/crescendo/variant_3.yaml +0 -0
  81. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/data/templates/crescendo/variant_4.yaml +0 -0
  82. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/data/templates/crescendo/variant_5.yaml +0 -0
  83. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/deep_inception.py +0 -0
  84. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/drattack.py +0 -0
  85. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/events.py +0 -0
  86. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/goat.py +0 -0
  87. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/gptfuzzer.py +0 -0
  88. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/image.py +0 -0
  89. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/multimodal.py +0 -0
  90. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/pair.py +0 -0
  91. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/prompt.py +0 -0
  92. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/rainbow.py +0 -0
  93. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/renellm.py +0 -0
  94. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/reporting/__init__.py +0 -0
  95. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/reporting/json_report.py +0 -0
  96. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/reporting/llm_summary.py +0 -0
  97. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/reporting/markdown.py +0 -0
  98. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/airt/tap.py +0 -0
  99. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/__init__.py +0 -0
  100. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/api/__init__.py +0 -0
  101. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/api/client.py +0 -0
  102. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/api/models.py +0 -0
  103. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/cli/__init__.py +0 -0
  104. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/cli/airt.py +0 -0
  105. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/cli/capability.py +0 -0
  106. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/cli/dataset.py +0 -0
  107. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/cli/evaluation.py +0 -0
  108. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/cli/main.py +0 -0
  109. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/cli/model.py +0 -0
  110. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/cli/optimize.py +0 -0
  111. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/cli/runtime.py +0 -0
  112. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/cli/shared.py +0 -0
  113. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/cli/train.py +0 -0
  114. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/cli/worlds.py +0 -0
  115. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/print_mode.py +0 -0
  116. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/server/__init__.py +0 -0
  117. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/server/auth.py +0 -0
  118. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/server/default-agent/tools/coding.py +0 -0
  119. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/server/default-agent/tools/subagent.py +0 -0
  120. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/server/session.py +0 -0
  121. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/server/system-prompt.md +0 -0
  122. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/server/utils.py +0 -0
  123. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/__init__.py +0 -0
  124. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/commands.py +0 -0
  125. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/connection.py +0 -0
  126. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/runtime_cache.py +0 -0
  127. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/screens/__init__.py +0 -0
  128. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/screens/base.py +0 -0
  129. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/screens/console.py +0 -0
  130. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/screens/environments.py +0 -0
  131. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/screens/evaluations.py +0 -0
  132. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/screens/model_picker.py +0 -0
  133. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/screens/runtimes.py +0 -0
  134. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/screens/sandboxes.py +0 -0
  135. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/screens/secrets.py +0 -0
  136. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/screens/sessions.py +0 -0
  137. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/screens/traces.py +0 -0
  138. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/screens/workspaces.py +0 -0
  139. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/update_check.py +0 -0
  140. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/widgets/__init__.py +0 -0
  141. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/widgets/agent_dialog.py +0 -0
  142. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/widgets/agent_suggester.py +0 -0
  143. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/widgets/composer.py +0 -0
  144. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/widgets/context_bar.py +0 -0
  145. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/widgets/flash.py +0 -0
  146. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/widgets/header_bar.py +0 -0
  147. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/widgets/help_panel.py +0 -0
  148. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/widgets/mcp_dialog.py +0 -0
  149. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/widgets/mention_overlay.py +0 -0
  150. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/widgets/message_queue.py +0 -0
  151. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/widgets/overlay_mixin.py +0 -0
  152. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/widgets/permission_prompt.py +0 -0
  153. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/widgets/prompt_info.py +0 -0
  154. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/widgets/session_sidebar.py +0 -0
  155. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/widgets/status_bar.py +0 -0
  156. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/widgets/throbber.py +0 -0
  157. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/widgets/tool.py +0 -0
  158. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/app/tui/widgets/tools_dialog.py +0 -0
  159. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/capabilities/__init__.py +0 -0
  160. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/capabilities/capability.py +0 -0
  161. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/capabilities/loader.py +0 -0
  162. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/capabilities/sync.py +0 -0
  163. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/capabilities/tool_rules.py +0 -0
  164. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/capabilities/types.py +0 -0
  165. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/__init__.py +0 -0
  166. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/conditions.py +0 -0
  167. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/discovery.py +0 -0
  168. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/environment.py +0 -0
  169. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/exceptions.py +0 -0
  170. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/execution.py +0 -0
  171. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/hook.py +0 -0
  172. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/judge.py +0 -0
  173. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/load.py +0 -0
  174. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/log.py +0 -0
  175. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/meta/__init__.py +0 -0
  176. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/meta/config.py +0 -0
  177. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/meta/context.py +0 -0
  178. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/meta/hydrate.py +0 -0
  179. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/meta/introspect.py +0 -0
  180. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/metric.py +0 -0
  181. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/object.py +0 -0
  182. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/scorer.py +0 -0
  183. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/serialization.py +0 -0
  184. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/stopping.py +0 -0
  185. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/task.py +0 -0
  186. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/transforms.py +0 -0
  187. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/types/__init__.py +0 -0
  188. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/types/audio.py +0 -0
  189. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/types/base.py +0 -0
  190. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/types/common.py +0 -0
  191. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/types/image.py +0 -0
  192. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/types/object_3d.py +0 -0
  193. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/types/table.py +0 -0
  194. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/types/text.py +0 -0
  195. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/types/video.py +0 -0
  196. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/core/util.py +0 -0
  197. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/datasets/__init__.py +0 -0
  198. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/datasets/dataset.py +0 -0
  199. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/datasets/hf.py +0 -0
  200. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/datasets/local.py +0 -0
  201. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/evaluations/__init__.py +0 -0
  202. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/evaluations/console.py +0 -0
  203. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/evaluations/evaluation.py +0 -0
  204. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/evaluations/events.py +0 -0
  205. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/evaluations/format.py +0 -0
  206. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/evaluations/result.py +0 -0
  207. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/evaluations/sample.py +0 -0
  208. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/generators/__init__.py +0 -0
  209. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/generators/caching.py +0 -0
  210. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/generators/chat.py +0 -0
  211. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/generators/data.py +0 -0
  212. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/generators/exceptions.py +0 -0
  213. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/generators/generator/__init__.py +0 -0
  214. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/generators/generator/base.py +0 -0
  215. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/generators/generator/http.py +0 -0
  216. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/generators/generator/litellm_.py +0 -0
  217. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/generators/generator/transformers_.py +0 -0
  218. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/generators/generator/vllm_.py +0 -0
  219. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/generators/message.py +0 -0
  220. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/generators/models.py +0 -0
  221. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/generators/parsing.py +0 -0
  222. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/generators/tokenizer/__init__.py +0 -0
  223. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/generators/tokenizer/base.py +0 -0
  224. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/generators/tokenizer/transformers_.py +0 -0
  225. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/generators/utils.py +0 -0
  226. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/models/__init__.py +0 -0
  227. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/models/hf.py +0 -0
  228. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/models/local.py +0 -0
  229. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/models/model.py +0 -0
  230. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/optimization/__init__.py +0 -0
  231. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/optimization/adapters/__init__.py +0 -0
  232. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/optimization/adapters/agent.py +0 -0
  233. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/optimization/api.py +0 -0
  234. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/optimization/backends/__init__.py +0 -0
  235. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/optimization/backends/base.py +0 -0
  236. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/optimization/backends/gepa.py +0 -0
  237. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/optimization/collectors.py +0 -0
  238. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/optimization/config.py +0 -0
  239. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/optimization/console.py +0 -0
  240. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/optimization/events.py +0 -0
  241. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/optimization/format.py +0 -0
  242. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/optimization/jobs.py +0 -0
  243. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/optimization/result.py +0 -0
  244. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/optimization/sampler.py +0 -0
  245. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/optimization/sampling.py +0 -0
  246. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/optimization/search.py +0 -0
  247. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/optimization/stopping.py +0 -0
  248. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/optimization/study.py +0 -0
  249. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/optimization/trial.py +0 -0
  250. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/packaging/__init__.py +0 -0
  251. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/packaging/loader.py +0 -0
  252. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/packaging/manifest.py +0 -0
  253. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/packaging/oci.py +0 -0
  254. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/packaging/package.py +0 -0
  255. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/py.typed +0 -0
  256. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/samplers/__init__.py +0 -0
  257. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/samplers/boundary.py +0 -0
  258. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/samplers/fuzzing.py +0 -0
  259. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/samplers/graph.py +0 -0
  260. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/samplers/grid.py +0 -0
  261. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/samplers/image.py +0 -0
  262. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/samplers/mapelites.py +0 -0
  263. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/samplers/optuna.py +0 -0
  264. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/samplers/random.py +0 -0
  265. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/samplers/registry.py +0 -0
  266. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/samplers/strategy.py +0 -0
  267. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/__init__.py +0 -0
  268. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/advanced_jailbreak_detection.py +0 -0
  269. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/agent_security.py +0 -0
  270. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/agentic.py +0 -0
  271. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/agentic_workflow.py +0 -0
  272. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/classification.py +0 -0
  273. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/consistency.py +0 -0
  274. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/contains.py +0 -0
  275. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/cosine_sim.py +0 -0
  276. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/credentials.py +0 -0
  277. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/crucible.py +0 -0
  278. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/documentation_security.py +0 -0
  279. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/exfiltration_detection.py +0 -0
  280. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/format.py +0 -0
  281. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/harm.py +0 -0
  282. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/ide_security.py +0 -0
  283. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/image.py +0 -0
  284. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/json.py +0 -0
  285. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/judge.py +0 -0
  286. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/length.py +0 -0
  287. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/lexical.py +0 -0
  288. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/mcp_security.py +0 -0
  289. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/memorization.py +0 -0
  290. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/multi_agent_security.py +0 -0
  291. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/pii.py +0 -0
  292. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/prompt_leak.py +0 -0
  293. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/readability.py +0 -0
  294. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/reasoning_security.py +0 -0
  295. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/sentiment.py +0 -0
  296. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/scorers/similarity.py +0 -0
  297. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/storage/__init__.py +0 -0
  298. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/storage/providers.py +0 -0
  299. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/storage/session_store.py +0 -0
  300. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/storage/storage.py +0 -0
  301. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/tools/__init__.py +0 -0
  302. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/tools/_ripgrep.py +0 -0
  303. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/tools/apply_patch.py +0 -0
  304. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/tools/editing.py +0 -0
  305. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/tools/execute.py +0 -0
  306. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/tools/fetch.py +0 -0
  307. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/tools/glob.py +0 -0
  308. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/tools/grep.py +0 -0
  309. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/tools/interaction.py +0 -0
  310. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/tools/ls.py +0 -0
  311. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/tools/memory.py +0 -0
  312. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/tools/read.py +0 -0
  313. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/tools/task.py +0 -0
  314. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/tools/think.py +0 -0
  315. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/tools/todo.py +0 -0
  316. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/tools/web_search.py +0 -0
  317. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/tools/write.py +0 -0
  318. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/tracing/__init__.py +0 -0
  319. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/tracing/constants.py +0 -0
  320. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/tracing/convert.py +0 -0
  321. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/tracing/exporter.py +0 -0
  322. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/tracing/exporters.py +0 -0
  323. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/tracing/span.py +0 -0
  324. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/tracing/spans.py +0 -0
  325. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/tracing/trace_converter.py +0 -0
  326. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/__init__.py +0 -0
  327. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/base.py +0 -0
  328. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/dpo.py +0 -0
  329. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/etl/__init__.py +0 -0
  330. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/etl/_common.py +0 -0
  331. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/etl/rl.py +0 -0
  332. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/etl/sft.py +0 -0
  333. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/etl/worlds.py +0 -0
  334. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/events.py +0 -0
  335. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/grpo.py +0 -0
  336. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/jobs.py +0 -0
  337. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/ppo.py +0 -0
  338. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/prime.py +0 -0
  339. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/ray/__init__.py +0 -0
  340. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/ray/async_trainer.py +0 -0
  341. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/ray/config.py +0 -0
  342. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/ray/coordinator.py +0 -0
  343. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/ray/distributed.py +0 -0
  344. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/ray/dpo.py +0 -0
  345. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/ray/experience.py +0 -0
  346. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/ray/fsdp2_learner.py +0 -0
  347. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/ray/inference.py +0 -0
  348. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/ray/learner.py +0 -0
  349. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/ray/multi_turn.py +0 -0
  350. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/ray/ppo.py +0 -0
  351. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/ray/reward_model.py +0 -0
  352. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/ray/rollout_env.py +0 -0
  353. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/ray/rollout_worker.py +0 -0
  354. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/ray/sft.py +0 -0
  355. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/ray/trainer.py +0 -0
  356. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/recipes.py +0 -0
  357. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/rewards/__init__.py +0 -0
  358. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/rewards/aggregator.py +0 -0
  359. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/rewards/functions.py +0 -0
  360. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/rewards/scorer_bridge.py +0 -0
  361. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/rewards/shaping.py +0 -0
  362. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/rewards/types.py +0 -0
  363. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/rollouts/__init__.py +0 -0
  364. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/rollouts/adapters.py +0 -0
  365. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/rollouts/orchestrator.py +0 -0
  366. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/rollouts/types.py +0 -0
  367. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/rollouts/worlds.py +0 -0
  368. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/serving/__init__.py +0 -0
  369. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/serving/vllm_client.py +0 -0
  370. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/sft.py +0 -0
  371. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/tinker/__init__.py +0 -0
  372. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/tinker/config.py +0 -0
  373. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/tinker/data.py +0 -0
  374. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/tinker/renderer.py +0 -0
  375. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/tinker/rl.py +0 -0
  376. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/tinker/trainer.py +0 -0
  377. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/tinker_sft.py +0 -0
  378. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/training/utils.py +0 -0
  379. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/__init__.py +0 -0
  380. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/advanced_jailbreak.py +0 -0
  381. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/adversarial_suffix.py +0 -0
  382. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/agent_skill.py +0 -0
  383. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/agentic_workflow.py +0 -0
  384. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/audio.py +0 -0
  385. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/browser_agent_attacks.py +0 -0
  386. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/cipher.py +0 -0
  387. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/constitutional.py +0 -0
  388. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/document.py +0 -0
  389. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/documentation_poison.py +0 -0
  390. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/encoding.py +0 -0
  391. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/exfiltration.py +0 -0
  392. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/flip_attack.py +0 -0
  393. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/guardrail_bypass.py +0 -0
  394. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/ide_injection.py +0 -0
  395. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/image.py +0 -0
  396. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/injection.py +0 -0
  397. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/json_tools.py +0 -0
  398. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/language.py +0 -0
  399. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/logic_bomb.py +0 -0
  400. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/mcp_attacks.py +0 -0
  401. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/multi_agent_attacks.py +0 -0
  402. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/persuasion.py +0 -0
  403. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/perturbation.py +0 -0
  404. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/pii_extraction.py +0 -0
  405. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/pythonic_tools.py +0 -0
  406. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/rag_poisoning.py +0 -0
  407. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/reasoning_attacks.py +0 -0
  408. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/refine.py +0 -0
  409. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/response_steering.py +0 -0
  410. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/stylistic.py +0 -0
  411. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/substitution.py +0 -0
  412. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/swap.py +0 -0
  413. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/system_prompt_extraction.py +0 -0
  414. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/text.py +0 -0
  415. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/video.py +0 -0
  416. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/transforms/xml_tools.py +0 -0
  417. {dreadnode-2.0.3 → dreadnode-2.0.5}/dreadnode/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dreadnode
3
- Version: 2.0.3
3
+ Version: 2.0.5
4
4
  Summary: Dreadnode SDK
5
5
  Project-URL: Homepage, https://dreadnode.io
6
6
  Project-URL: Documentation, https://docs.dreadnode.io
@@ -19,7 +19,7 @@ Requires-Dist: gepa>=0.1.1
19
19
  Requires-Dist: httpx<1.0.0,>=0.28.0
20
20
  Requires-Dist: jsonpath-ng>=1.7.0
21
21
  Requires-Dist: jsonref>=1.1.0
22
- Requires-Dist: litellm>=1.80.11
22
+ Requires-Dist: litellm<=1.82.2,>=1.80.11
23
23
  Requires-Dist: logfire<=3.20.0,>=3.5.3
24
24
  Requires-Dist: loguru>=0.7.3
25
25
  Requires-Dist: mcp<2.0.0,>=1.25.0
@@ -4,7 +4,7 @@ from datetime import datetime, timezone
4
4
  from uuid import UUID, uuid4
5
5
 
6
6
  import typing_extensions as te
7
- from pydantic import BaseModel, ConfigDict, Field
7
+ from pydantic import BaseModel, ConfigDict, Field, PlainSerializer, WithJsonSchema
8
8
  from rich.console import Console, ConsoleOptions, RenderableType, RenderResult
9
9
  from rich.panel import Panel
10
10
  from rich.rule import Rule
@@ -55,6 +55,14 @@ if t.TYPE_CHECKING:
55
55
  AgentEventT = te.TypeVar("AgentEventT", bound="AgentEvent", default="AgentEvent")
56
56
  AgentStepT = te.TypeVar("AgentStepT", bound="AgentStep", default="AgentStep")
57
57
  AgentStopReason = t.Literal["finished", "max_steps_reached", "error", "stalled"]
58
+
59
+ # Reusable annotation for error fields that store raw exception objects.
60
+ # Pydantic can't serialize exceptions to JSON, so we coerce to str on serialization.
61
+ # Same pattern as dreadnode.generators.chat.Chat.error.
62
+ _ErrorSerializer = PlainSerializer(lambda x: str(x), return_type=str, when_used="json-unless-none")
63
+ _ErrorJsonSchema = WithJsonSchema({"type": "string", "description": "Error message"})
64
+ SerializableError = t.Annotated[BaseException, _ErrorSerializer, _ErrorJsonSchema]
65
+ SerializableException = t.Annotated[Exception, _ErrorSerializer, _ErrorJsonSchema]
58
66
  AgentStatus = t.Literal["running", "stalled", "errored", "finished"]
59
67
 
60
68
 
@@ -139,7 +147,7 @@ class AgentStep(AgentEvent):
139
147
  step: int = 0
140
148
  messages: list[Message] = Field(default_factory=list)
141
149
  usage: Usage = Usage(input_tokens=0, output_tokens=0, total_tokens=0)
142
- error: Exception | None = None
150
+ error: SerializableException | None = None
143
151
  stop: bool | None = None
144
152
 
145
153
  @property
@@ -231,7 +239,7 @@ class AgentEnd(AgentEvent):
231
239
  """
232
240
 
233
241
  stop_reason: AgentStopReason
234
- error: Exception | str | None = None
242
+ error: SerializableException | str | None = None
235
243
 
236
244
  def _get_data(self) -> dict[str, t.Any]:
237
245
  error = self.error
@@ -336,7 +344,7 @@ class AgentError(AgentEvent):
336
344
  error: The error that occurred during the agent's execution.
337
345
  """
338
346
 
339
- error: BaseException
347
+ error: SerializableError
340
348
 
341
349
  def _get_data(self) -> dict[str, t.Any]:
342
350
  return {
@@ -543,7 +551,7 @@ class ToolError(AgentEvent):
543
551
  """
544
552
 
545
553
  tool_call: ToolCall
546
- error: BaseException
554
+ error: SerializableError
547
555
 
548
556
  def _get_data(self) -> dict[str, t.Any]:
549
557
  return {
@@ -817,7 +825,7 @@ class GenerationError(AgentEvent):
817
825
  """
818
826
 
819
827
  generator: Generator | None = None
820
- error: BaseException
828
+ error: SerializableError
821
829
  step: int = 0
822
830
  messages: list["Message"] = Field(default_factory=list)
823
831
 
@@ -158,6 +158,7 @@ def sync(
158
158
  *,
159
159
  force: t.Annotated[bool, cyclopts.Parameter(negative=())] = False,
160
160
  public: t.Annotated[bool, cyclopts.Parameter(negative=())] = False,
161
+ workers: t.Annotated[int, cyclopts.Parameter(help="Parallel upload workers.")] = 8,
161
162
  registry: RegistryConfig = RegistryConfig(),
162
163
  ) -> None:
163
164
  """Sync task environments from a directory to the platform."""
@@ -166,7 +167,9 @@ def sync(
166
167
  directory,
167
168
  force=force,
168
169
  public=public,
170
+ max_workers=workers,
169
171
  on_progress=_sync_progress,
172
+ on_status=lambda msg: print(msg),
170
173
  )
171
174
 
172
175
  total = len(result.uploaded) + len(result.skipped) + len(result.failed)
@@ -1819,13 +1819,37 @@ class Dreadnode:
1819
1819
  result.blobs_skipped += oci_result.blobs_existed
1820
1820
  return result
1821
1821
 
1822
+ def _fetch_remote_task_digests(self, org: str) -> dict[str, str]:
1823
+ """Fetch all remote task OCI digests in bulk via paginated list.
1824
+
1825
+ Returns a mapping of ``{task_name: oci_layer_sha}`` for every task
1826
+ that has a recorded OCI digest.
1827
+ """
1828
+ digests: dict[str, str] = {}
1829
+ page = 1
1830
+ while True:
1831
+ resp = self.api.list_tasks(org, page=page, limit=100)
1832
+ for item in resp.get("tasks", []):
1833
+ name = item.get("name")
1834
+ raw = item.get("oci_digest")
1835
+ if name and isinstance(raw, str) and raw:
1836
+ sha = raw.split(":", 1)[-1] if ":" in raw else raw
1837
+ digests[name] = sha
1838
+ total = resp.get("total", 0)
1839
+ if page * 100 >= total:
1840
+ break
1841
+ page += 1
1842
+ return digests
1843
+
1822
1844
  def sync_environments(
1823
1845
  self,
1824
1846
  directory: str | Path,
1825
1847
  *,
1826
1848
  force: bool = False,
1827
1849
  public: bool = False,
1850
+ max_workers: int = 8,
1828
1851
  on_progress: t.Callable[[str, str, str | None], None] | None = None,
1852
+ on_status: t.Callable[[str], None] | None = None,
1829
1853
  ) -> EnvironmentSyncResult:
1830
1854
  """Sync task environments from a directory to the platform.
1831
1855
 
@@ -1837,11 +1861,15 @@ class Dreadnode:
1837
1861
  directory: Root directory containing task subdirectories.
1838
1862
  force: Upload even when the remote SHA matches.
1839
1863
  public: Set ``is_public=True`` after upload.
1864
+ max_workers: Maximum parallel build/upload threads.
1840
1865
  on_progress: Optional callback ``(name, status, error)`` for each task.
1841
1866
 
1842
1867
  Returns:
1843
1868
  :class:`EnvironmentSyncResult` with uploaded/skipped/failed details.
1844
1869
  """
1870
+ import concurrent.futures
1871
+ import threading
1872
+
1845
1873
  from dreadnode.packaging.oci import build_environment
1846
1874
 
1847
1875
  if not self.can_sync:
@@ -1851,13 +1879,18 @@ class Dreadnode:
1851
1879
 
1852
1880
  from dreadnode.packaging.task_validation import discover_task_directories
1853
1881
 
1882
+ _status = on_status or (lambda _msg: None)
1883
+
1854
1884
  root = Path(directory).resolve()
1855
1885
  if not root.is_dir():
1856
1886
  raise FileNotFoundError(f"Task directory not found: {root}")
1857
1887
 
1858
1888
  org = self.session.org_key
1859
1889
 
1890
+ _status("Discovering tasks...")
1860
1891
  task_dirs, conflicts = discover_task_directories(root)
1892
+ _status(f"Found {len(task_dirs)} task(s)")
1893
+
1861
1894
  if conflicts and on_progress:
1862
1895
  for parent, nested in conflicts:
1863
1896
  on_progress(
@@ -1869,9 +1902,17 @@ class Dreadnode:
1869
1902
  result = EnvironmentSyncResult(
1870
1903
  failed=[(nested.name, f"nested inside {parent.name}") for parent, nested in conflicts],
1871
1904
  )
1872
- oci_client = self.storage.oci_client()
1873
1905
 
1874
- for task_dir in task_dirs:
1906
+ # Batch-fetch all remote digests (one paginated call vs N individual GETs)
1907
+ _status("Fetching remote digests...")
1908
+ remote_digests = self._fetch_remote_task_digests(org) if not force else {}
1909
+ _status(
1910
+ f"Fetched {len(remote_digests)} remote digest(s), syncing with {max_workers} workers..."
1911
+ )
1912
+
1913
+ lock = threading.Lock()
1914
+
1915
+ def _sync_one(task_dir: Path) -> None:
1875
1916
  dir_name = task_dir.name
1876
1917
  try:
1877
1918
  env_name, env_version = _load_environment_metadata(task_dir)
@@ -1883,33 +1924,44 @@ class Dreadnode:
1883
1924
  raise ValueError("Environment OCI image has no layers") # noqa: TRY301
1884
1925
  local_sha = image.layers[0].digest.split(":", 1)[-1]
1885
1926
 
1886
- remote_sha = self._get_remote_task_sha(org, env_name)
1927
+ remote_sha = remote_digests.get(env_name)
1887
1928
  if not force and remote_sha and remote_sha == local_sha:
1888
- result.skipped.append(env_name)
1929
+ if public:
1930
+ self.api.update_task_visibility(org, env_name, is_public=True)
1931
+ with lock:
1932
+ result.skipped.append(env_name)
1889
1933
  if on_progress:
1890
1934
  on_progress(env_name, "skipped", None)
1891
- continue
1935
+ return
1892
1936
 
1937
+ # Each thread gets its own OCI client (own httpx.Client)
1938
+ oci_client = self.storage.oci_client()
1893
1939
  push_result = oci_client.push(resolved_name, env_version, image)
1894
1940
  if not push_result.success:
1895
1941
  msg = "; ".join(push_result.errors) or "OCI push failed"
1896
- result.failed.append((env_name, msg))
1942
+ with lock:
1943
+ result.failed.append((env_name, msg))
1897
1944
  if on_progress:
1898
1945
  on_progress(env_name, "failed", msg)
1899
- continue
1946
+ return
1900
1947
 
1901
1948
  if public:
1902
1949
  self.api.update_task_visibility(org, env_name, is_public=True)
1903
1950
 
1904
- result.uploaded.append(env_name)
1951
+ with lock:
1952
+ result.uploaded.append(env_name)
1905
1953
  if on_progress:
1906
1954
  on_progress(env_name, "uploaded", None)
1907
1955
 
1908
1956
  except Exception as exc:
1909
- result.failed.append((dir_name, str(exc)))
1957
+ with lock:
1958
+ result.failed.append((dir_name, str(exc)))
1910
1959
  if on_progress:
1911
1960
  on_progress(dir_name, "failed", str(exc))
1912
1961
 
1962
+ with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as pool:
1963
+ list(pool.map(_sync_one, task_dirs))
1964
+
1913
1965
  return result
1914
1966
 
1915
1967
  def pull_package(
@@ -60,7 +60,7 @@ if t.TYPE_CHECKING:
60
60
  from dreadnode.storage import SessionRecord, SessionStore
61
61
 
62
62
  EventPayload = dict[str, t.Any]
63
- _TERMINAL_CHAT_EVENT_TYPES = frozenset({"agentend", "error"})
63
+ _TERMINAL_CHAT_EVENT_TYPES = frozenset({"agentend", "error", "cancelled"})
64
64
  DEFAULT_MODEL = "anthropic/claude-sonnet-4-20250514"
65
65
  _DREADNODE_LLM_BASE_ENV = "DREADNODE_LLM_BASE"
66
66
  _DREADNODE_LLM_API_KEY_ENV = "DREADNODE_LLM_API_KEY"
@@ -812,6 +812,7 @@ def create_agent(
812
812
  instructions=instructions,
813
813
  tools=tools,
814
814
  hooks=hooks,
815
+ max_steps=500,
815
816
  )
816
817
 
817
818
 
@@ -1826,6 +1827,28 @@ class SessionRuntime:
1826
1827
  if self._processing_task is not None and not self._processing_task.done():
1827
1828
  self._processing_task.cancel()
1828
1829
 
1830
+ async def cancel(self) -> bool:
1831
+ """Cancel the active turn and drain queued requests.
1832
+
1833
+ Returns True if a running turn was cancelled, False if already idle.
1834
+ """
1835
+ was_busy = False
1836
+ if self._processing_task is not None and not self._processing_task.done():
1837
+ self._processing_task.cancel()
1838
+ was_busy = True
1839
+ # Wait for the task to finish its cancellation cleanup
1840
+ with suppress(asyncio.CancelledError):
1841
+ await self._processing_task
1842
+
1843
+ # Drain any queued requests so their SSE connections terminate
1844
+ async with self._queue_lock:
1845
+ while self._queue:
1846
+ queued = self._queue.popleft()
1847
+ await queued.event_queue.put(None)
1848
+ self._processing_task = None
1849
+
1850
+ return was_busy
1851
+
1829
1852
  def persist_manifest(self) -> None:
1830
1853
  """Persist minimal runtime metadata needed to rebind the session."""
1831
1854
  self._ensure_session_dir()
@@ -1905,6 +1928,7 @@ class SessionRuntime:
1905
1928
  )
1906
1929
  _log_chat_timing(self.session_id, "processor_start", request.queued_at_monotonic)
1907
1930
 
1931
+ cancelled = False
1908
1932
  try:
1909
1933
  if request.model is not None and request.model != self.model:
1910
1934
  self.model = request.model
@@ -2004,13 +2028,25 @@ class SessionRuntime:
2004
2028
  # Clear cached agent so restore paths create fresh
2005
2029
  self._agent = None
2006
2030
  self._persist_state()
2031
+ except asyncio.CancelledError:
2032
+ cancelled = True
2033
+ logger.info("Session {}: turn cancelled by user", self.session_id[:8])
2034
+ # Persist whatever trajectory we have so far
2035
+ self._agent = None
2036
+ self._persist_state()
2037
+ await request.event_queue.put(
2038
+ {"type": "cancelled", "data": {"reason": "user_interrupt"}}
2039
+ )
2040
+ # Don't re-raise — let the method exit cleanly so cancel() can drain remaining queue
2041
+ return
2007
2042
  except Exception as exc:
2008
2043
  logger.exception("Error during chat for session {}", self.session_id)
2009
2044
  await request.event_queue.put({"type": "error", "error": str(exc)})
2010
2045
  finally:
2011
2046
  logger.debug("Session {}: chat turn complete", self.session_id[:8])
2012
2047
  _log_chat_timing(self.session_id, "processor_complete", request.queued_at_monotonic)
2013
- await request.event_queue.put(None)
2048
+ if not cancelled:
2049
+ await request.event_queue.put(None)
2014
2050
 
2015
2051
  def _first_user_preview(self, max_len: int = 200) -> str | None:
2016
2052
  """Extract preview text from the first user message in the trajectory."""
@@ -2228,6 +2264,21 @@ async def reset_session(session_id: str) -> JSONResponse:
2228
2264
  return JSONResponse(content={"status": "reset", "session_id": session_id})
2229
2265
 
2230
2266
 
2267
+ @app.post("/api/sessions/{session_id}/cancel")
2268
+ async def cancel_session(session_id: str) -> JSONResponse:
2269
+ """Cancel the active turn and drain queued requests for a session."""
2270
+ session = get_state().get_session(session_id)
2271
+ if session is None:
2272
+ raise HTTPException(status_code=404, detail=f"Session not found: {session_id}")
2273
+ was_busy = await session.cancel()
2274
+ return JSONResponse(
2275
+ content={
2276
+ "status": "cancelled" if was_busy else "idle",
2277
+ "session_id": session_id,
2278
+ }
2279
+ )
2280
+
2281
+
2231
2282
  @app.post("/api/sessions/{session_id}/compact")
2232
2283
  async def compact_session(session_id: str, body: dict[str, t.Any] | None = None) -> JSONResponse:
2233
2284
  """Compact a session's conversation history (CMP-API-001)."""