dreadnode 2.0.32__tar.gz → 2.0.33__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 (660) hide show
  1. {dreadnode-2.0.32 → dreadnode-2.0.33}/PKG-INFO +1 -1
  2. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/__init__.py +10 -0
  3. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/message_parts.py +81 -1
  4. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/multimodal.py +214 -18
  5. dreadnode-2.0.33/dreadnode/airt/targets/__init__.py +39 -0
  6. dreadnode-2.0.33/dreadnode/airt/targets/auth.py +74 -0
  7. dreadnode-2.0.33/dreadnode/airt/targets/factory.py +39 -0
  8. dreadnode-2.0.33/dreadnode/airt/targets/http.py +45 -0
  9. dreadnode-2.0.33/dreadnode/airt/targets/message.py +38 -0
  10. dreadnode-2.0.33/dreadnode/airt/targets/spec.py +57 -0
  11. dreadnode-2.0.33/dreadnode/airt/targets/streaming/__init__.py +9 -0
  12. dreadnode-2.0.33/dreadnode/airt/targets/streaming/nova_sonic.py +279 -0
  13. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/model_catalog.py +34 -1
  14. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/server/app.py +18 -0
  15. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/server/websocket.py +7 -0
  16. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/app.py +4 -3
  17. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/model_variants.py +32 -0
  18. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/sessions_manager.py +31 -1
  19. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/conversation.py +27 -11
  20. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/projects.md +2 -0
  21. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/generators/generator/litellm_.py +82 -4
  22. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/generators/message.py +11 -10
  23. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/__init__.py +3 -1
  24. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/judge.py +195 -1
  25. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tracing/constants.py +6 -0
  26. {dreadnode-2.0.32 → dreadnode-2.0.33}/pyproject.toml +1 -1
  27. {dreadnode-2.0.32 → dreadnode-2.0.33}/.gitignore +0 -0
  28. {dreadnode-2.0.32 → dreadnode-2.0.33}/LICENSE +0 -0
  29. {dreadnode-2.0.32 → dreadnode-2.0.33}/README.md +0 -0
  30. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/__init__.py +0 -0
  31. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/__main__.py +0 -0
  32. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/agents/__init__.py +0 -0
  33. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/agents/agent.py +0 -0
  34. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/agents/engines/AGENTS.md +0 -0
  35. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/agents/engines/__init__.py +0 -0
  36. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/agents/engines/base.py +0 -0
  37. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/agents/engines/claude_code.py +0 -0
  38. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/agents/engines/native.py +0 -0
  39. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/agents/events.py +0 -0
  40. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/agents/exceptions.py +0 -0
  41. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/agents/format.py +0 -0
  42. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/agents/hooks.py +0 -0
  43. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/agents/judge.py +0 -0
  44. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/agents/mcp/__init__.py +0 -0
  45. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/agents/mcp/auth.py +0 -0
  46. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/agents/mcp/client.py +0 -0
  47. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/agents/mcp/config.py +0 -0
  48. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/agents/mcp/server.py +0 -0
  49. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/agents/process_judge.py +0 -0
  50. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/agents/reactions.py +0 -0
  51. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/agents/skills.py +0 -0
  52. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/agents/stopping.py +0 -0
  53. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/agents/subagent.py +0 -0
  54. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/agents/tool_resolution.py +0 -0
  55. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/agents/tools.py +0 -0
  56. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/agents/trajectory.py +0 -0
  57. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/adversarial_reasoning.py +0 -0
  58. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/advpromptier.py +0 -0
  59. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/alignment_faking.py +0 -0
  60. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/analogy_escalation.py +0 -0
  61. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/analytics/__init__.py +0 -0
  62. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/analytics/aggregator.py +0 -0
  63. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/analytics/classifier.py +0 -0
  64. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/analytics/compliance.py +0 -0
  65. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/analytics/engine.py +0 -0
  66. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/analytics/recommendations.py +0 -0
  67. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/analytics/types.py +0 -0
  68. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/aprt_progressive.py +0 -0
  69. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/assessment.py +0 -0
  70. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/attention_shifting.py +0 -0
  71. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/autodan_turbo.py +0 -0
  72. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/autoredteamer.py +0 -0
  73. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/beast.py +0 -0
  74. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/compliance/__init__.py +0 -0
  75. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/compliance/atlas.py +0 -0
  76. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/compliance/nist.py +0 -0
  77. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/compliance/owasp.py +0 -0
  78. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/compliance/owasp_agentic.py +0 -0
  79. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/compliance/saif.py +0 -0
  80. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/constants.py +0 -0
  81. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/cot_jailbreak.py +0 -0
  82. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/crescendo.py +0 -0
  83. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/data/__init__.py +0 -0
  84. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/data/assets/audio/adversarial_query.mp3 +0 -0
  85. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/data/assets/image/bomb.jpg +0 -0
  86. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/data/assets/image/meth.png +0 -0
  87. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/data/prompts/adversarial_benchmark_subset.csv +0 -0
  88. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/data/prompts/ai_safety.csv +0 -0
  89. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/data/rubrics/data_exfiltration.yaml +0 -0
  90. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/data/rubrics/goal_hijacking.yaml +0 -0
  91. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/data/rubrics/idor.yaml +0 -0
  92. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/data/rubrics/memory_poisoning.yaml +0 -0
  93. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/data/rubrics/privilege_escalation.yaml +0 -0
  94. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/data/rubrics/rce.yaml +0 -0
  95. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/data/rubrics/scope_creep.yaml +0 -0
  96. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/data/rubrics/tool_chaining.yaml +0 -0
  97. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/data/rubrics/tool_selection_safety.yaml +0 -0
  98. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/data/rubrics/unbounded_agency.yaml +0 -0
  99. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/data/rubrics/web_chatbot_security.yaml +0 -0
  100. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/data/templates/crescendo/variant_1.yaml +0 -0
  101. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/data/templates/crescendo/variant_2.yaml +0 -0
  102. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/data/templates/crescendo/variant_3.yaml +0 -0
  103. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/data/templates/crescendo/variant_4.yaml +0 -0
  104. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/data/templates/crescendo/variant_5.yaml +0 -0
  105. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/deep_inception.py +0 -0
  106. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/drattack.py +0 -0
  107. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/echo_chamber.py +0 -0
  108. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/events.py +0 -0
  109. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/genetic_persona.py +0 -0
  110. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/goat.py +0 -0
  111. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/goat_v2.py +0 -0
  112. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/gptfuzzer.py +0 -0
  113. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/humor_bypass.py +0 -0
  114. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/image.py +0 -0
  115. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/j2_meta.py +0 -0
  116. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/jbdistill.py +0 -0
  117. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/jbfuzz.py +0 -0
  118. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/lrm_autonomous.py +0 -0
  119. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/mapf.py +0 -0
  120. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/nexus.py +0 -0
  121. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/pair.py +0 -0
  122. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/persona_hijack.py +0 -0
  123. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/prompt.py +0 -0
  124. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/quantization_safety.py +0 -0
  125. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/rainbow.py +0 -0
  126. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/refusal_aware.py +0 -0
  127. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/renellm.py +0 -0
  128. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/reporting/__init__.py +0 -0
  129. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/reporting/json_report.py +0 -0
  130. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/reporting/llm_summary.py +0 -0
  131. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/reporting/markdown.py +0 -0
  132. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/reward_hacking.py +0 -0
  133. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/salami_slicing.py +0 -0
  134. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/self_persuasion.py +0 -0
  135. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/siren.py +0 -0
  136. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/tap.py +0 -0
  137. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/templatefuzz.py +0 -0
  138. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/tmap_trajectory.py +0 -0
  139. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/trojail.py +0 -0
  140. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/airt/watermark_removal.py +0 -0
  141. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/__init__.py +0 -0
  142. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/api/__init__.py +0 -0
  143. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/api/client.py +0 -0
  144. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/api/models.py +0 -0
  145. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/__init__.py +0 -0
  146. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/airt.py +0 -0
  147. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/args.py +0 -0
  148. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/capability.py +0 -0
  149. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/dataset.py +0 -0
  150. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/environment.py +0 -0
  151. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/evaluation.py +0 -0
  152. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/inference_model.py +0 -0
  153. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/judge.py +0 -0
  154. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/main.py +0 -0
  155. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/model.py +0 -0
  156. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/optimize.py +0 -0
  157. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/runtime.py +0 -0
  158. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/sandbox.py +0 -0
  159. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/secret.py +0 -0
  160. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/session.py +0 -0
  161. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/shared.py +0 -0
  162. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/task.py +0 -0
  163. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/task_set.py +0 -0
  164. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/templates/__init__.py +0 -0
  165. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/templates/init/__init__.py +0 -0
  166. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/templates/init/challenge/Dockerfile +0 -0
  167. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/templates/init/docker-compose.yaml +0 -0
  168. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/templates/init/provision.sh +0 -0
  169. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/templates/init/solution.sh +0 -0
  170. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/templates/init/task-remote.yaml.tmpl +0 -0
  171. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/templates/init/task.yaml.tmpl +0 -0
  172. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/templates/init/teardown.sh +0 -0
  173. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/templates/init/verify.sh +0 -0
  174. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/train.py +0 -0
  175. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/cli/worlds.py +0 -0
  176. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/client/__init__.py +0 -0
  177. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/client/interactive.py +0 -0
  178. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/client/managed_client.py +0 -0
  179. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/client/models.py +0 -0
  180. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/client/runtime_client.py +0 -0
  181. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/client/transports.py +0 -0
  182. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/config.py +0 -0
  183. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/env.py +0 -0
  184. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/main.py +0 -0
  185. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/paths.py +0 -0
  186. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/print_mode.py +0 -0
  187. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/server/__init__.py +0 -0
  188. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/server/auth.py +0 -0
  189. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/server/capability_manager.py +0 -0
  190. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/server/model_resolution.py +0 -0
  191. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/server/prompt.py +0 -0
  192. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/server/prompt_registry.py +0 -0
  193. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/server/runtime_events.py +0 -0
  194. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/server/session_hydrator.py +0 -0
  195. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/server/session_persistence.py +0 -0
  196. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/server/turn_coordinator.py +0 -0
  197. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/server/utils.py +0 -0
  198. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/server/worker_manager.py +0 -0
  199. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/server/ws_auth.py +0 -0
  200. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/__init__.py +0 -0
  201. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/auth_flow.py +0 -0
  202. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/capabilities_manager.py +0 -0
  203. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/command_dispatcher.py +0 -0
  204. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/commands.py +0 -0
  205. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/connection.py +0 -0
  206. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/dreadnode.tcss +0 -0
  207. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/error_handler.py +0 -0
  208. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/model_manager.py +0 -0
  209. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/profile_manager.py +0 -0
  210. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/runtime_cache.py +0 -0
  211. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/screen_router.py +0 -0
  212. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/screens/__init__.py +0 -0
  213. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/screens/auth.py +0 -0
  214. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/screens/base.py +0 -0
  215. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/screens/capabilities.py +0 -0
  216. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/screens/capability_docs.py +0 -0
  217. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/screens/connection_error.py +0 -0
  218. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/screens/console.py +0 -0
  219. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/screens/environments.py +0 -0
  220. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/screens/evaluations.py +0 -0
  221. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/screens/models.py +0 -0
  222. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/screens/raw_spans.py +0 -0
  223. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/screens/readme.py +0 -0
  224. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/screens/runtimes.py +0 -0
  225. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/screens/sandboxes.py +0 -0
  226. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/screens/secrets.py +0 -0
  227. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/screens/services.py +0 -0
  228. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/screens/sessions.py +0 -0
  229. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/screens/theme_showcase.py +0 -0
  230. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/screens/traces.py +0 -0
  231. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/screens/workspaces.py +0 -0
  232. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/spans_reader.py +0 -0
  233. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/status_messages.py +0 -0
  234. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/theme.py +0 -0
  235. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/tool_format.py +0 -0
  236. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/turn_coordinator.py +0 -0
  237. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/turn_lifecycle.py +0 -0
  238. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/turn_reducer.py +0 -0
  239. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/turn_state_phase.py +0 -0
  240. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/update_check.py +0 -0
  241. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/__init__.py +0 -0
  242. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/agent_dialog.py +0 -0
  243. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/agent_suggester.py +0 -0
  244. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/composer.py +0 -0
  245. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/confirm_modal.py +0 -0
  246. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/context_bar.py +0 -0
  247. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/flash.py +0 -0
  248. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/header_bar.py +0 -0
  249. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/help_panel.py +0 -0
  250. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/human_prompt.py +0 -0
  251. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/mention_overlay.py +0 -0
  252. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/message_queue.py +0 -0
  253. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/new_messages_pill.py +0 -0
  254. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/overlay_mixin.py +0 -0
  255. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/permission_prompt.py +0 -0
  256. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/profile_dialog.py +0 -0
  257. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/prompt_info.py +0 -0
  258. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/rewind_picker.py +0 -0
  259. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/session_sidebar.py +0 -0
  260. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/skills_dialog.py +0 -0
  261. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/slash_overlay.py +0 -0
  262. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/status_bar.py +0 -0
  263. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/throbber.py +0 -0
  264. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/tool.py +0 -0
  265. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/tool_progress.py +0 -0
  266. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/tools_dialog.py +0 -0
  267. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/welcome.py +0 -0
  268. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/widgets/whoami.py +0 -0
  269. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/app/tui/wire_events.py +0 -0
  270. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/__init__.py +0 -0
  271. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/MAINTAINING.md +0 -0
  272. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/agents/dreadnode.md +0 -0
  273. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/capability.yaml +0 -0
  274. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/SKILL.md +0 -0
  275. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/capability-improvement.md +0 -0
  276. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/methodology-grounding.md +0 -0
  277. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/prior-art-audit.md +0 -0
  278. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/promoting-capabilities.md +0 -0
  279. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/quality-bar.md +0 -0
  280. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/INDEX.md +0 -0
  281. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/agents.md +0 -0
  282. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/custom-engines.md +0 -0
  283. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/dependencies-and-checks.md +0 -0
  284. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/engines.md +0 -0
  285. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/env-vars.md +0 -0
  286. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/events.md +0 -0
  287. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/flags.md +0 -0
  288. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/hooks.md +0 -0
  289. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/installing.md +0 -0
  290. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/manifest.md +0 -0
  291. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/mcp-servers.md +0 -0
  292. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/overview.md +0 -0
  293. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/policies.md +0 -0
  294. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/publishing.md +0 -0
  295. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/quickstart.md +0 -0
  296. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/skills.md +0 -0
  297. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/tools.md +0 -0
  298. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/workers-reference.md +0 -0
  299. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/workers.md +0 -0
  300. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/writing-skills.md +0 -0
  301. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/sdk/agents.md +0 -0
  302. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/sdk/capabilities.md +0 -0
  303. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/tui/default-tools.md +0 -0
  304. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references-and-depth.md +0 -0
  305. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/runtime-default-capability.md +0 -0
  306. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/SKILL.md +0 -0
  307. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/INDEX.md +0 -0
  308. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/airt.md +0 -0
  309. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/capability.md +0 -0
  310. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/dataset.md +0 -0
  311. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/env.md +0 -0
  312. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/evaluation.md +0 -0
  313. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/inference-model.md +0 -0
  314. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/main.md +0 -0
  315. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/model.md +0 -0
  316. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/optimize.md +0 -0
  317. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/overview.md +0 -0
  318. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/runtime.md +0 -0
  319. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/sandbox.md +0 -0
  320. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/secret.md +0 -0
  321. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/task-set.md +0 -0
  322. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/task.md +0 -0
  323. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/train.md +0 -0
  324. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/worlds.md +0 -0
  325. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/getting-started/authentication.md +0 -0
  326. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/SKILL.md +0 -0
  327. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/INDEX.md +0 -0
  328. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/capabilities/installing.md +0 -0
  329. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/capabilities/overview.md +0 -0
  330. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/getting-started/authentication.md +0 -0
  331. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/getting-started/overview.md +0 -0
  332. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/getting-started/quickstart.md +0 -0
  333. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/chat-models.md +0 -0
  334. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/credits.md +0 -0
  335. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/organizations.md +0 -0
  336. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/overview.md +0 -0
  337. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/secrets.md +0 -0
  338. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/settings.md +0 -0
  339. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/users.md +0 -0
  340. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/workspaces.md +0 -0
  341. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/configuration.md +0 -0
  342. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/managing.md +0 -0
  343. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/manifest-reference.md +0 -0
  344. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/overview.md +0 -0
  345. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/quickstart.md +0 -0
  346. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/serve.md +0 -0
  347. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/sandboxes/environment-lifecycle.md +0 -0
  348. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/sandboxes/inspecting.md +0 -0
  349. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/sandboxes/overview.md +0 -0
  350. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/sandboxes/runtime-limits.md +0 -0
  351. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/getting-started/SKILL.md +0 -0
  352. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/dreadnode/skills/research-capabilities/SKILL.md +0 -0
  353. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/self-improvement/.gitignore +0 -0
  354. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/self-improvement/capability.yaml +0 -0
  355. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/self-improvement/hooks/__init__.py +0 -0
  356. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/self-improvement/hooks/observer.py +0 -0
  357. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/__init__.py +0 -0
  358. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/classifier.py +0 -0
  359. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/reflector_goal.py +0 -0
  360. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/skill_io.py +0 -0
  361. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/self-improvement/skills-promoted/.gitkeep +0 -0
  362. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/self-improvement/skills-proposed/.gitkeep +0 -0
  363. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/self-improvement/tools/__init__.py +0 -0
  364. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/self-improvement/tools/reflector.py +0 -0
  365. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/builtin_capabilities/self-improvement/tools/skill_stats.py +0 -0
  366. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/capabilities/__init__.py +0 -0
  367. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/capabilities/capability.py +0 -0
  368. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/capabilities/flags.py +0 -0
  369. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/capabilities/install.py +0 -0
  370. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/capabilities/loader.py +0 -0
  371. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/capabilities/sync.py +0 -0
  372. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/capabilities/tool_rules.py +0 -0
  373. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/capabilities/types.py +0 -0
  374. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/capabilities/worker.py +0 -0
  375. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/capabilities/worker_runner.py +0 -0
  376. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/__init__.py +0 -0
  377. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/conditions.py +0 -0
  378. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/discovery.py +0 -0
  379. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/environment.py +0 -0
  380. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/exceptions.py +0 -0
  381. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/execution.py +0 -0
  382. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/hook.py +0 -0
  383. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/judge.py +0 -0
  384. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/load.py +0 -0
  385. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/log.py +0 -0
  386. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/meta/__init__.py +0 -0
  387. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/meta/config.py +0 -0
  388. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/meta/context.py +0 -0
  389. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/meta/hydrate.py +0 -0
  390. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/meta/introspect.py +0 -0
  391. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/metric.py +0 -0
  392. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/object.py +0 -0
  393. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/scorer.py +0 -0
  394. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/serialization.py +0 -0
  395. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/stopping.py +0 -0
  396. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/task.py +0 -0
  397. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/templating.py +0 -0
  398. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/transforms.py +0 -0
  399. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/types/__init__.py +0 -0
  400. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/types/audio.py +0 -0
  401. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/types/base.py +0 -0
  402. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/types/common.py +0 -0
  403. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/types/image.py +0 -0
  404. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/types/object_3d.py +0 -0
  405. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/types/table.py +0 -0
  406. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/types/text.py +0 -0
  407. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/types/video.py +0 -0
  408. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/core/util.py +0 -0
  409. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/datasets/__init__.py +0 -0
  410. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/datasets/dataset.py +0 -0
  411. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/datasets/hf.py +0 -0
  412. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/datasets/local.py +0 -0
  413. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/evaluations/__init__.py +0 -0
  414. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/evaluations/console.py +0 -0
  415. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/evaluations/evaluation.py +0 -0
  416. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/evaluations/events.py +0 -0
  417. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/evaluations/format.py +0 -0
  418. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/evaluations/result.py +0 -0
  419. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/evaluations/sample.py +0 -0
  420. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/generators/__init__.py +0 -0
  421. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/generators/caching.py +0 -0
  422. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/generators/chat.py +0 -0
  423. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/generators/data.py +0 -0
  424. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/generators/exceptions.py +0 -0
  425. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/generators/generator/__init__.py +0 -0
  426. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/generators/generator/base.py +0 -0
  427. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/generators/generator/http.py +0 -0
  428. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/generators/generator/transformers_.py +0 -0
  429. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/generators/generator/vllm_.py +0 -0
  430. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/generators/models.py +0 -0
  431. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/generators/parsing.py +0 -0
  432. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/generators/proxy.py +0 -0
  433. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/generators/tokenizer/__init__.py +0 -0
  434. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/generators/tokenizer/base.py +0 -0
  435. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/generators/tokenizer/transformers_.py +0 -0
  436. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/generators/utils.py +0 -0
  437. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/items/__init__.py +0 -0
  438. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/items/config.py +0 -0
  439. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/items/models.py +0 -0
  440. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/judges/__init__.py +0 -0
  441. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/judges/outcome.py +0 -0
  442. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/judges/trajectory.py +0 -0
  443. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/judges/trajectory_tools.py +0 -0
  444. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/models/__init__.py +0 -0
  445. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/models/hf.py +0 -0
  446. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/models/local.py +0 -0
  447. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/models/model.py +0 -0
  448. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/optimization/__init__.py +0 -0
  449. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/optimization/adapters/__init__.py +0 -0
  450. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/optimization/adapters/_env_eval.py +0 -0
  451. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/optimization/adapters/agent.py +0 -0
  452. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/optimization/adapters/env.py +0 -0
  453. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/optimization/adapters/runtime.py +0 -0
  454. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/optimization/adapters/stack.py +0 -0
  455. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/optimization/api.py +0 -0
  456. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/optimization/backends/__init__.py +0 -0
  457. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/optimization/backends/base.py +0 -0
  458. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/optimization/backends/gepa.py +0 -0
  459. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/optimization/collectors.py +0 -0
  460. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/optimization/config.py +0 -0
  461. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/optimization/console.py +0 -0
  462. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/optimization/events.py +0 -0
  463. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/optimization/format.py +0 -0
  464. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/optimization/jobs.py +0 -0
  465. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/optimization/result.py +0 -0
  466. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/optimization/sampler.py +0 -0
  467. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/optimization/sampling.py +0 -0
  468. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/optimization/search.py +0 -0
  469. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/optimization/stopping.py +0 -0
  470. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/optimization/study.py +0 -0
  471. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/optimization/trial.py +0 -0
  472. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/packaging/__init__.py +0 -0
  473. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/packaging/loader.py +0 -0
  474. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/packaging/manifest.py +0 -0
  475. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/packaging/oci.py +0 -0
  476. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/packaging/package.py +0 -0
  477. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/packaging/task_validation.py +0 -0
  478. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/policies/__init__.py +0 -0
  479. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/policies/guard.py +0 -0
  480. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/policies/reconciliation.py +0 -0
  481. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/policies/rubrics/process/default.yaml +0 -0
  482. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/py.typed +0 -0
  483. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/samplers/__init__.py +0 -0
  484. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/samplers/boundary.py +0 -0
  485. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/samplers/fuzzing.py +0 -0
  486. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/samplers/graph.py +0 -0
  487. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/samplers/grid.py +0 -0
  488. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/samplers/image.py +0 -0
  489. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/samplers/mapelites.py +0 -0
  490. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/samplers/optuna.py +0 -0
  491. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/samplers/random.py +0 -0
  492. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/samplers/registry.py +0 -0
  493. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/samplers/strategy.py +0 -0
  494. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/advanced_jailbreak_detection.py +0 -0
  495. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/agent_security.py +0 -0
  496. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/agentic.py +0 -0
  497. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/agentic_workflow.py +0 -0
  498. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/attack_outcome.py +0 -0
  499. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/classification.py +0 -0
  500. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/consistency.py +0 -0
  501. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/contains.py +0 -0
  502. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/cosine_sim.py +0 -0
  503. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/credentials.py +0 -0
  504. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/crucible.py +0 -0
  505. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/documentation_security.py +0 -0
  506. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/exfiltration_detection.py +0 -0
  507. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/format.py +0 -0
  508. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/harm.py +0 -0
  509. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/ide_security.py +0 -0
  510. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/image.py +0 -0
  511. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/json.py +0 -0
  512. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/judge_ensemble.py +0 -0
  513. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/length.py +0 -0
  514. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/lexical.py +0 -0
  515. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/mcp_security.py +0 -0
  516. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/memorization.py +0 -0
  517. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/multi_agent_security.py +0 -0
  518. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/pii.py +0 -0
  519. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/prompt_leak.py +0 -0
  520. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/readability.py +0 -0
  521. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/reasoning_security.py +0 -0
  522. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/sentiment.py +0 -0
  523. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/similarity.py +0 -0
  524. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/structural_detection.py +0 -0
  525. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/scorers/supply_chain_detection.py +0 -0
  526. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/storage/__init__.py +0 -0
  527. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/storage/providers.py +0 -0
  528. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/storage/session_store.py +0 -0
  529. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/storage/storage.py +0 -0
  530. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tools/__init__.py +0 -0
  531. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tools/_ripgrep.py +0 -0
  532. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tools/apply_patch.py +0 -0
  533. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tools/dreadnode_cli.py +0 -0
  534. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tools/editing.py +0 -0
  535. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tools/execute.py +0 -0
  536. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tools/fetch.py +0 -0
  537. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tools/glob.py +0 -0
  538. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tools/grep.py +0 -0
  539. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tools/interaction.py +0 -0
  540. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tools/ls.py +0 -0
  541. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tools/memory.py +0 -0
  542. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tools/project_memory.py +0 -0
  543. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tools/read.py +0 -0
  544. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tools/report.py +0 -0
  545. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tools/report_items.py +0 -0
  546. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tools/task.py +0 -0
  547. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tools/think.py +0 -0
  548. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tools/todo.py +0 -0
  549. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tools/trajectory_search.py +0 -0
  550. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tools/web_extract.py +0 -0
  551. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tools/web_search.py +0 -0
  552. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tools/write.py +0 -0
  553. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tracing/__init__.py +0 -0
  554. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tracing/convert.py +0 -0
  555. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tracing/exporter.py +0 -0
  556. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tracing/exporters.py +0 -0
  557. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tracing/span.py +0 -0
  558. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tracing/spans.py +0 -0
  559. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/tracing/trace_converter.py +0 -0
  560. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/__init__.py +0 -0
  561. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/_progress.py +0 -0
  562. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/base.py +0 -0
  563. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/dpo.py +0 -0
  564. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/env_rollouts.py +0 -0
  565. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/etl/__init__.py +0 -0
  566. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/etl/_common.py +0 -0
  567. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/etl/rl.py +0 -0
  568. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/etl/sft.py +0 -0
  569. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/etl/worlds.py +0 -0
  570. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/events.py +0 -0
  571. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/grpo.py +0 -0
  572. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/jobs.py +0 -0
  573. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/models.py +0 -0
  574. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/ppo.py +0 -0
  575. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/prime.py +0 -0
  576. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/ray/__init__.py +0 -0
  577. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/ray/async_trainer.py +0 -0
  578. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/ray/config.py +0 -0
  579. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/ray/coordinator.py +0 -0
  580. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/ray/distributed.py +0 -0
  581. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/ray/dpo.py +0 -0
  582. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/ray/experience.py +0 -0
  583. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/ray/fsdp2_learner.py +0 -0
  584. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/ray/inference.py +0 -0
  585. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/ray/learner.py +0 -0
  586. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/ray/multi_turn.py +0 -0
  587. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/ray/ppo.py +0 -0
  588. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/ray/reward_model.py +0 -0
  589. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/ray/rollout_env.py +0 -0
  590. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/ray/rollout_worker.py +0 -0
  591. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/ray/sft.py +0 -0
  592. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/ray/trainer.py +0 -0
  593. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/recipes.py +0 -0
  594. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/rewards/__init__.py +0 -0
  595. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/rewards/aggregator.py +0 -0
  596. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/rewards/functions.py +0 -0
  597. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/rewards/scorer_bridge.py +0 -0
  598. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/rewards/shaping.py +0 -0
  599. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/rewards/types.py +0 -0
  600. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/rollouts/__init__.py +0 -0
  601. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/rollouts/adapters.py +0 -0
  602. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/rollouts/agent_rollout.py +0 -0
  603. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/rollouts/orchestrator.py +0 -0
  604. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/rollouts/types.py +0 -0
  605. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/rollouts/worlds.py +0 -0
  606. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/serving/__init__.py +0 -0
  607. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/serving/vllm_client.py +0 -0
  608. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/sft.py +0 -0
  609. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/tinker/__init__.py +0 -0
  610. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/tinker/config.py +0 -0
  611. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/tinker/data.py +0 -0
  612. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/tinker/renderer.py +0 -0
  613. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/tinker/rl.py +0 -0
  614. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/tinker/trainer.py +0 -0
  615. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/tinker_sft.py +0 -0
  616. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/training/utils.py +0 -0
  617. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/__init__.py +0 -0
  618. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/advanced_jailbreak.py +0 -0
  619. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/adversarial_suffix.py +0 -0
  620. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/agent_skill.py +0 -0
  621. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/agentic_workflow.py +0 -0
  622. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/audio.py +0 -0
  623. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/backdoor_finetune.py +0 -0
  624. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/browser_agent_attacks.py +0 -0
  625. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/cipher.py +0 -0
  626. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/competitive_parity.py +0 -0
  627. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/constitutional.py +0 -0
  628. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/document.py +0 -0
  629. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/documentation_poison.py +0 -0
  630. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/encoding.py +0 -0
  631. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/exfiltration.py +0 -0
  632. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/flip_attack.py +0 -0
  633. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/guardrail_bypass.py +0 -0
  634. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/ide_injection.py +0 -0
  635. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/image.py +0 -0
  636. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/injection.py +0 -0
  637. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/json_tools.py +0 -0
  638. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/language.py +0 -0
  639. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/logic_bomb.py +0 -0
  640. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/mcp_attacks.py +0 -0
  641. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/multi_agent_attacks.py +0 -0
  642. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/multimodal_attacks.py +0 -0
  643. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/persuasion.py +0 -0
  644. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/perturbation.py +0 -0
  645. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/pii_extraction.py +0 -0
  646. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/pythonic_tools.py +0 -0
  647. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/rag_poisoning.py +0 -0
  648. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/reasoning_attacks.py +0 -0
  649. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/refine.py +0 -0
  650. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/response_steering.py +0 -0
  651. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/structural_exploits.py +0 -0
  652. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/stylistic.py +0 -0
  653. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/substitution.py +0 -0
  654. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/supply_chain.py +0 -0
  655. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/swap.py +0 -0
  656. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/system_prompt_extraction.py +0 -0
  657. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/text.py +0 -0
  658. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/video.py +0 -0
  659. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/transforms/xml_tools.py +0 -0
  660. {dreadnode-2.0.32 → dreadnode-2.0.33}/dreadnode/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dreadnode
3
- Version: 2.0.32
3
+ Version: 2.0.33
4
4
  Summary: Dreadnode SDK
5
5
  Project-URL: Homepage, https://dreadnode.io
6
6
  Project-URL: Documentation, https://docs.dreadnode.io
@@ -101,6 +101,12 @@ from dreadnode.airt.salami_slicing import salami_slicing_attack
101
101
  from dreadnode.airt.self_persuasion import self_persuasion_attack
102
102
  from dreadnode.airt.siren import siren_attack
103
103
  from dreadnode.airt.tap import tap_attack
104
+ from dreadnode.airt.targets import (
105
+ TargetAuth,
106
+ TargetSpec,
107
+ build_target,
108
+ nova_sonic_target,
109
+ )
104
110
  from dreadnode.airt.templatefuzz import templatefuzz_attack
105
111
  from dreadnode.airt.tmap_trajectory import tmap_trajectory_attack
106
112
  from dreadnode.airt.trojail import trojail_attack
@@ -108,6 +114,8 @@ from dreadnode.airt.watermark_removal import watermark_removal_attack
108
114
 
109
115
  __all__ = [
110
116
  "Assessment",
117
+ "TargetAuth",
118
+ "TargetSpec",
111
119
  "adversarial_reasoning_attack",
112
120
  "advpromptier_attack",
113
121
  "alignment_faking_attack",
@@ -117,6 +125,7 @@ __all__ = [
117
125
  "autodan_turbo_attack",
118
126
  "autoredteamer_attack",
119
127
  "beast_attack",
128
+ "build_target",
120
129
  "cot_jailbreak_attack",
121
130
  "crescendo_attack",
122
131
  "deep_inception_attack",
@@ -136,6 +145,7 @@ __all__ = [
136
145
  "multimodal_attack",
137
146
  "nes_attack",
138
147
  "nexus_attack",
148
+ "nova_sonic_target",
139
149
  "pair_attack",
140
150
  "persona_hijack_attack",
141
151
  "prompt_attack",
@@ -46,6 +46,18 @@ def _mime_for_extension(ext: str | None, default: str) -> str:
46
46
  return _MIME_BY_EXT.get(ext.lower().lstrip("."), default)
47
47
 
48
48
 
49
+ # Legacy/alias MIME types that browsers handle poorly, mapped to the standard.
50
+ _MIME_ALIASES = {
51
+ "audio/x-wav": "audio/wav",
52
+ "audio/wave": "audio/wav",
53
+ "audio/x-pn-wav": "audio/wav",
54
+ }
55
+
56
+
57
+ def _normalize_mime(mime: str | None) -> str | None:
58
+ return _MIME_ALIASES.get(mime, mime) if mime else mime
59
+
60
+
49
61
  def text_part(
50
62
  text: str,
51
63
  *,
@@ -106,9 +118,14 @@ def _media_part(
106
118
  ) -> dict[str, t.Any]:
107
119
  """Build a media message part, storing bytes as a content-addressed artifact."""
108
120
  meta = _store_bytes_as_artifact(span, data, filename=filename)
121
+ # Prefer the caller's canonical media_type over log_artifact's guessed MIME:
122
+ # Python's mimetypes maps `.wav` to the legacy `audio/x-wav`, which some
123
+ # browsers refuse to play in an <audio> element. `_normalize_mime` maps such
124
+ # aliases back to the standard type.
125
+ resolved_mime = _normalize_mime(media_type or (meta.get("mime_type") if meta else None))
109
126
  source: dict[str, t.Any] = {
110
127
  "ref": "artifact",
111
- "media_type": (meta.get("mime_type") if meta else None) or media_type,
128
+ "media_type": resolved_mime,
112
129
  "byte_size": (meta.get("size") if meta else None) or len(data),
113
130
  "filename": (meta.get("name") if meta else None) or filename,
114
131
  }
@@ -226,12 +243,75 @@ def response_to_parts(
226
243
  content-addressed artifacts; text is inlined.
227
244
  """
228
245
  from dreadnode.core.types import Audio, Image, Video
246
+ from dreadnode.generators.message import (
247
+ ContentAudioInput,
248
+ ContentImageUrl,
249
+ ContentText,
250
+ ContentVideoUrl,
251
+ )
229
252
 
230
253
  parts: list[dict[str, t.Any]] = []
231
254
 
232
255
  def _walk(value: t.Any) -> None:
233
256
  if value is None:
234
257
  return
258
+ # SDK message content-part types (media-out responses: image/audio/video
259
+ # generated by the target land here). Extract the real bytes/text instead
260
+ # of stringifying the part's repr.
261
+ if isinstance(value, ContentText):
262
+ if value.text:
263
+ parts.append(text_part(value.text))
264
+ return
265
+ if isinstance(value, ContentImageUrl):
266
+ url = value.image_url.url
267
+ mime = "image/png"
268
+ if url.startswith("data:") and ";" in url:
269
+ mime = url[5:].split(";", 1)[0] or mime
270
+ parts.append(
271
+ _media_part(
272
+ span,
273
+ value.to_bytes(),
274
+ kind="image",
275
+ media_type=mime,
276
+ filename="response_image.png",
277
+ transform=None,
278
+ variant="output",
279
+ caption=None,
280
+ )
281
+ )
282
+ return
283
+ if isinstance(value, ContentAudioInput):
284
+ fmt = getattr(value.input_audio, "format", "wav") or "wav"
285
+ parts.append(
286
+ _media_part(
287
+ span,
288
+ value.to_bytes(),
289
+ kind="audio",
290
+ media_type=_mime_for_extension(fmt, "audio/wav"),
291
+ filename=f"response_audio.{fmt}",
292
+ transform=None,
293
+ variant="output",
294
+ caption=None,
295
+ )
296
+ )
297
+ return
298
+ if isinstance(value, ContentVideoUrl):
299
+ import base64 as _b64
300
+
301
+ data = _b64.b64decode(value.file.file_data.split(",", 1)[-1])
302
+ parts.append(
303
+ _media_part(
304
+ span,
305
+ data,
306
+ kind="video",
307
+ media_type=value.file.mimetype or "video/mp4",
308
+ filename=value.file.filename or "response_video.mp4",
309
+ transform=None,
310
+ variant="output",
311
+ caption=None,
312
+ )
313
+ )
314
+ return
235
315
  if isinstance(value, str):
236
316
  if value:
237
317
  parts.append(text_part(value))
@@ -6,12 +6,14 @@ Probes multimodal models (vision, audio) with transformed inputs.
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
+ import contextlib
9
10
  import typing as t
10
11
 
11
12
  from dreadnode.core.transforms import Transform
12
13
  from dreadnode.generators.message import (
13
14
  ContentAudioInput,
14
15
  ContentImageUrl,
16
+ ContentText,
15
17
  ContentVideoUrl,
16
18
  Message,
17
19
  )
@@ -206,11 +208,122 @@ def _log_multimodal_parts(
206
208
  logger.debug("Failed to log multimodal message parts", exc_info=True)
207
209
 
208
210
 
211
+ def _extract_response_modalities(response: t.Any) -> dict[str, t.Any]:
212
+ """Decode a target response into per-modality scorable values.
213
+
214
+ Returns a dict keyed by modality (``"text"``/``"image"``/``"audio"``/``"video"``).
215
+ Text is a single concatenated string; media modalities are decoded into native
216
+ SDK media objects (``Image``/``Audio``/``Video``) so a modality-specific scorer
217
+ receives the type it expects. A str response yields ``{"text": <str>}`` — the
218
+ exact value the single-scorer path scored before, keeping text-out behaviour
219
+ (and every other attack that never emits media) unchanged.
220
+ """
221
+ from dreadnode.core.types import Audio, Image, Video
222
+
223
+ out: dict[str, t.Any] = {}
224
+ texts: list[str] = []
225
+
226
+ def _walk(value: t.Any) -> None:
227
+ if value is None:
228
+ return
229
+ if isinstance(value, str):
230
+ if value:
231
+ texts.append(value)
232
+ elif isinstance(value, ContentText):
233
+ if value.text:
234
+ texts.append(value.text)
235
+ elif isinstance(value, ContentImageUrl):
236
+ with contextlib.suppress(Exception):
237
+ out["image"] = Image(value.to_bytes())
238
+ elif isinstance(value, ContentAudioInput):
239
+ fmt = getattr(value.input_audio, "format", "wav") or "wav"
240
+ with contextlib.suppress(Exception):
241
+ out["audio"] = Audio(value.to_bytes(), format=fmt)
242
+ elif isinstance(value, ContentVideoUrl):
243
+ with contextlib.suppress(Exception):
244
+ import base64
245
+
246
+ data = base64.b64decode(value.file.file_data.split(",", 1)[-1])
247
+ ext = (value.file.mimetype or "video/mp4").split("/")[-1]
248
+ out["video"] = Video(data, format=ext)
249
+ elif isinstance(value, Image):
250
+ out["image"] = value
251
+ elif isinstance(value, Audio):
252
+ out["audio"] = value
253
+ elif isinstance(value, Video):
254
+ out["video"] = value
255
+ elif isinstance(value, (list, tuple)):
256
+ for item in value:
257
+ _walk(item)
258
+ elif isinstance(value, dict):
259
+ for key in ("content", "content_parts", "parts", "text"):
260
+ if key in value:
261
+ _walk(value[key])
262
+ break
263
+ else:
264
+ content = getattr(value, "content_parts", None) or getattr(value, "content", None)
265
+ if content is not None and not isinstance(content, str):
266
+ _walk(content)
267
+
268
+ _walk(response)
269
+ if texts:
270
+ out["text"] = "\n".join(texts)
271
+ return out
272
+
273
+
274
+ async def _score_multimodal_response(
275
+ response: t.Any,
276
+ *,
277
+ text_scorer: Scorer[t.Any],
278
+ response_scorers: dict[str, Scorer[t.Any]] | None,
279
+ ) -> tuple[float, dict[str, float], str | None]:
280
+ """Score each response modality and aggregate the trial score by MAX.
281
+
282
+ Red-teaming aggregation is worst-case: if *any* output modality bypasses
283
+ safety, the attack succeeded, so the objective score is the maximum across
284
+ modalities. Per-modality scores are returned for display, and the winning
285
+ (max) modality's rationale is surfaced as the judge reasoning.
286
+
287
+ Backward compatible: with no ``response_scorers`` and a plain text (str)
288
+ response, this scores exactly the same string with ``text_scorer`` as the
289
+ prior single-``scorer.score(response)`` path did — text-out attacks and
290
+ non-multimodal attacks are unaffected. Media modalities with no configured
291
+ scorer are simply skipped (they can't be judged without a media scorer).
292
+ """
293
+ scorers: dict[str, Scorer[t.Any]] = dict(response_scorers or {})
294
+ scorers.setdefault("text", text_scorer)
295
+
296
+ modalities = _extract_response_modalities(response)
297
+ per_modality: dict[str, float] = {}
298
+ reasons: dict[str, str] = {}
299
+ for modality, value in modalities.items():
300
+ scorer = scorers.get(modality)
301
+ if scorer is None:
302
+ continue
303
+ metric = await scorer.score(value)
304
+ per_modality[modality] = float(metric.value)
305
+ reason = (getattr(metric, "attributes", None) or {}).get("reason")
306
+ if reason:
307
+ reasons[modality] = str(reason)
308
+
309
+ if not per_modality:
310
+ # Nothing decoded (or no applicable scorer) — score the raw response so a
311
+ # degenerate/unknown output shape still yields a metric.
312
+ metric = await text_scorer.score(response)
313
+ reason = (getattr(metric, "attributes", None) or {}).get("reason")
314
+ value = float(metric.value)
315
+ return value, {"text": value}, (str(reason) if reason else None)
316
+
317
+ winning = max(per_modality, key=per_modality.__getitem__)
318
+ return per_modality[winning], per_modality, reasons.get(winning)
319
+
320
+
209
321
  def multimodal_attack(
210
322
  goal: str,
211
323
  target: Task[..., str],
212
324
  scorer: Scorer[str],
213
325
  *,
326
+ response_scorers: dict[str, Scorer[t.Any]] | None = None,
214
327
  image: Image | None = None,
215
328
  audio: Audio | None = None,
216
329
  video: Video | None = None,
@@ -235,7 +348,17 @@ def multimodal_attack(
235
348
  Args:
236
349
  goal: The text prompt to send to the model (consistent with goat_attack/tap_attack API).
237
350
  target: Task that takes a Message and returns a string response.
238
- scorer: Scorer to evaluate target responses (e.g., jailbreak success).
351
+ scorer: Scorer to evaluate the target's *text* response (e.g., jailbreak
352
+ success). Also used as the default text scorer for multimodal output.
353
+ response_scorers: Optional per-modality scorers for multimodal *output*,
354
+ keyed by ``"text"``/``"image"``/``"audio"``/``"video"``. When a target
355
+ emits more than one modality (e.g. text + a generated image), each part
356
+ is scored by its modality's scorer and the trial's objective score is
357
+ the MAX across them — worst-case aggregation, since any single modality
358
+ bypassing safety counts as a successful jailbreak. Per-modality scores
359
+ are recorded on the trial span for display. Media modalities without a
360
+ configured scorer are skipped. Omit this for text-out targets — behaviour
361
+ is then identical to scoring the text response with ``scorer``.
239
362
  image: Optional image to include.
240
363
  audio: Optional audio to include.
241
364
  video: Optional video to include.
@@ -298,12 +421,70 @@ def multimodal_attack(
298
421
  applied,
299
422
  ) = await _apply_transforms(goal, image, audio, video, fitted_transforms)
300
423
 
301
- # Build message and call target
424
+ # Build message
302
425
  message = _build_message(
303
426
  transformed_goal, transformed_image, transformed_audio, transformed_video
304
427
  )
305
- span = await target.run(message)
306
- response = span.output
428
+
429
+ # Record the candidate ("attacker prompt") + trace Input as the transformed
430
+ # goal *text* BEFORE calling the target. If the target then fails (e.g. a
431
+ # provider error, so the response is empty), the finding still shows the
432
+ # real prompt instead of the sampler's {"iteration": N} search state.
433
+ # The Study logs `str(sample.input)` as `transformed_prompt`, so a dict
434
+ # input would render as `{'iteration': 0, 'image': Image(...)}`; the
435
+ # transformed media is carried losslessly in the message parts, so the
436
+ # text is all we log here.
437
+ trial = current_trial.get()
438
+ if trial is not None:
439
+ trial.candidate = transformed_goal
440
+ # The trial span's "candidate" input was logged at TrialStart with the
441
+ # sampler's raw search state; replace it with the goal text.
442
+ from dreadnode.tracing.span import current_task_span as _cts
443
+
444
+ _trial_span = _cts.get()
445
+ if _trial_span is not None:
446
+ with contextlib.suppress(Exception):
447
+ _trial_span._inputs = [
448
+ r for r in _trial_span._inputs if getattr(r, "name", None) != "candidate"
449
+ ]
450
+ _trial_span.log_input("candidate", transformed_goal)
451
+
452
+ # Call the target. If it errors (auth failure, unreachable model, rate limit,
453
+ # ...), record the error text as the response so the finding shows *why* it
454
+ # failed instead of an opaque "(no response)", then re-raise so the trial is
455
+ # still classified as an error (not a refusal).
456
+ try:
457
+ span = await target.run(message)
458
+ response = span.output
459
+ except Exception as target_exc:
460
+ error_text = f"[target error] {type(target_exc).__name__}: {str(target_exc)[:500]}"
461
+ with contextlib.suppress(Exception):
462
+ _log_multimodal_parts(
463
+ original_goal=goal,
464
+ transformed_goal=transformed_goal,
465
+ original_image=image,
466
+ transformed_image=transformed_image,
467
+ original_audio=audio,
468
+ transformed_audio=transformed_audio,
469
+ original_video=video,
470
+ transformed_video=transformed_video,
471
+ applied_transforms=applied,
472
+ response=error_text,
473
+ )
474
+ if trial is not None:
475
+ with contextlib.suppress(Exception):
476
+ trial.evaluation_result = EvalResult(
477
+ samples=[Sample(input=transformed_goal, output=error_text, index=iteration)]
478
+ )
479
+ from dreadnode.tracing.span import current_task_span as _err_span_ctx
480
+
481
+ _err_span = _err_span_ctx.get()
482
+ if _err_span is not None:
483
+ from dreadnode.tracing.constants import AIRT_ATTRIBUTE_JUDGE_REASONING
484
+
485
+ with contextlib.suppress(Exception):
486
+ _err_span.set_attribute(AIRT_ATTRIBUTE_JUDGE_REASONING, error_text)
487
+ raise
307
488
 
308
489
  # Persist the multimodal message parts (input + output) as content-addressed
309
490
  # artifacts on the trial span, so findings can render each part in the UI.
@@ -320,18 +501,7 @@ def multimodal_attack(
320
501
  response=response,
321
502
  )
322
503
 
323
- # Store sample in trial for tracking (include multimodal content for display)
324
- trial = current_trial.get()
325
504
  if trial is not None:
326
- # The candidate ("attacker prompt") AND the transformed prompt are the
327
- # transformed goal *text* — not the sampler's {"iteration": n} params
328
- # or a dict carrying the raw Image object. The Study logs
329
- # `str(sample.input)` as `transformed_prompt`, so a dict input would
330
- # render as `{'iteration': 0, 'image': Image(256x768x3 ...)}` in the
331
- # UI. The transformed media is carried losslessly in the message
332
- # parts (see `_log_multimodal_parts`), so the text is all we log here.
333
- trial.candidate = transformed_goal
334
-
335
505
  sample = Sample(
336
506
  input=transformed_goal,
337
507
  output=response,
@@ -339,9 +509,35 @@ def multimodal_attack(
339
509
  )
340
510
  trial.evaluation_result = EvalResult(samples=[sample])
341
511
 
342
- # Score the response
343
- score_result = await scorer.score(response)
344
- return {OBJECTIVE_SCORE_KEY: score_result.value}
512
+ # Score the response. For multimodal *output* (e.g. text + a generated
513
+ # image), each modality is scored by its own scorer and the objective is
514
+ # the MAX — any modality bypassing safety = a successful jailbreak. For a
515
+ # plain text response this reduces to scoring the text with `scorer`, so
516
+ # text-out attacks are unaffected. The winning modality's rationale is
517
+ # persisted so findings show *why* it scored ("Judge Reasoning"); the
518
+ # per-modality breakdown is recorded for display.
519
+ agg_score, modality_scores, reason = await _score_multimodal_response(
520
+ response, text_scorer=scorer, response_scorers=response_scorers
521
+ )
522
+ from dreadnode.tracing.span import current_task_span
523
+
524
+ trial_span = current_task_span.get()
525
+ if trial_span is not None:
526
+ if reason:
527
+ from dreadnode.tracing.constants import AIRT_ATTRIBUTE_JUDGE_REASONING
528
+
529
+ with contextlib.suppress(Exception):
530
+ trial_span.set_attribute(AIRT_ATTRIBUTE_JUDGE_REASONING, str(reason))
531
+ if len(modality_scores) > 1:
532
+ import json
533
+
534
+ from dreadnode.tracing.constants import AIRT_ATTRIBUTE_MODALITY_SCORES
535
+
536
+ with contextlib.suppress(Exception):
537
+ trial_span.set_attribute(
538
+ AIRT_ATTRIBUTE_MODALITY_SCORES, json.dumps(modality_scores)
539
+ )
540
+ return {OBJECTIVE_SCORE_KEY: agg_score}
345
541
 
346
542
  attack: Study[dict[str, t.Any]] = Study(
347
543
  name=name,
@@ -0,0 +1,39 @@
1
+ """Universal custom targets for AI red teaming.
2
+
3
+ A red-teaming *target* is any system you can send a message to and read a response
4
+ from. This package turns a declarative :class:`TargetSpec` into a dreadnode ``@task``
5
+ target that plugs straight into ``multimodal_attack`` / the attack studies —
6
+ regardless of where the model is deployed (AWS, Azure ML/AI Foundry, Google Vertex,
7
+ a self-hosted endpoint) or how it authenticates.
8
+
9
+ Two transports:
10
+
11
+ - ``http`` — request/response endpoints. Fully declarative: an endpoint, an auth scheme
12
+ (:class:`TargetAuth`), a JSON request template placing ``{prompt}`` / ``{image_b64}`` /
13
+ ``{audio_b64}`` / ``{video_b64}``, and a JSONPath to the response text. Covers Azure
14
+ ML / AI Foundry, Vertex ``predict``, SageMaker sync-invoke, OpenAI-compatible, etc.
15
+
16
+ - ``streaming`` — realtime / speech-to-speech protocols with a bespoke handshake. The
17
+ spec *selects* a protocol adapter; ``nova_sonic`` (Amazon Bedrock bidirectional S2S)
18
+ ships in :mod:`dreadnode.airt.targets.streaming`.
19
+
20
+ Module layout: :mod:`spec` (models) · :mod:`message` (payload conversion) ·
21
+ :mod:`auth` (auth strategies) · :mod:`http` (HTTP transport) · :mod:`streaming`
22
+ (streaming adapters) · :mod:`factory` (:func:`build_target` dispatcher).
23
+
24
+ Credentials are always read from environment variables / platform secrets — never
25
+ inlined into the spec.
26
+ """
27
+
28
+ from dreadnode.airt.targets.factory import build_target
29
+ from dreadnode.airt.targets.spec import AuthType, TargetAuth, TargetSpec, Transport
30
+ from dreadnode.airt.targets.streaming import nova_sonic_target
31
+
32
+ __all__ = [
33
+ "AuthType",
34
+ "TargetAuth",
35
+ "TargetSpec",
36
+ "Transport",
37
+ "build_target",
38
+ "nova_sonic_target",
39
+ ]
@@ -0,0 +1,74 @@
1
+ """HTTP authentication strategies.
2
+
3
+ Each auth mode reads its credential/identity from the environment or the platform's
4
+ credential chain — never from the spec. Provider SDKs (boto3, azure-identity,
5
+ google-auth) are imported dynamically so they stay off the SDK's hard-dependency set.
6
+ """
7
+
8
+ import importlib
9
+ import os
10
+
11
+ from dreadnode.airt.targets.spec import TargetSpec
12
+
13
+
14
+ def apply_auth(
15
+ spec: TargetSpec, headers: dict[str, str], url: str, content: bytes
16
+ ) -> dict[str, str]:
17
+ """Return the request headers with the spec's auth applied.
18
+
19
+ For ``aws_sigv4`` the returned dict is the fully signed header set (which depends on
20
+ ``url`` and ``content``); every other mode just adds an authorization header.
21
+ """
22
+ auth = spec.auth
23
+ headers = dict(headers)
24
+ if auth.type == "api_key":
25
+ headers[auth.header] = auth.value_prefix + os.environ.get(auth.env_var, "")
26
+ elif auth.type == "bearer":
27
+ headers["Authorization"] = "Bearer " + os.environ.get(auth.env_var, "")
28
+ elif auth.type == "azure_ad":
29
+ headers["Authorization"] = "Bearer " + azure_ad_token(auth.scope)
30
+ elif auth.type == "gcp":
31
+ headers["Authorization"] = "Bearer " + gcp_token(auth.scope)
32
+ elif auth.type == "aws_sigv4":
33
+ headers = sign_sigv4(url, content, headers, auth.region, auth.service)
34
+ return headers
35
+
36
+
37
+ def sign_sigv4(
38
+ url: str, body: bytes, headers: dict[str, str], region: str, service: str
39
+ ) -> dict[str, str]:
40
+ """Sign a POST with AWS SigV4 using the default credential chain (env/profile/role)."""
41
+ boto3 = importlib.import_module("boto3")
42
+ sigv4_auth = importlib.import_module("botocore.auth").SigV4Auth
43
+ aws_request = importlib.import_module("botocore.awsrequest").AWSRequest
44
+
45
+ creds = boto3.Session().get_credentials()
46
+ if creds is None:
47
+ raise RuntimeError("aws_sigv4 auth requires AWS credentials (env vars, profile, or role)")
48
+ req = aws_request(method="POST", url=url, data=body, headers=headers)
49
+ sigv4_auth(creds.get_frozen_credentials(), service, region).add_auth(req)
50
+ return dict(req.headers)
51
+
52
+
53
+ def azure_ad_token(scope: str) -> str:
54
+ """Acquire an Entra token via DefaultAzureCredential (managed identity, workload
55
+ identity, env creds, or ``az login`` — in that precedence)."""
56
+ default_azure_credential = importlib.import_module("azure.identity").DefaultAzureCredential
57
+
58
+ return default_azure_credential().get_token(scope).token
59
+
60
+
61
+ def gcp_token(scope: str) -> str:
62
+ """Acquire a token via Google Application Default Credentials (service account,
63
+ workload identity, or ``gcloud`` login)."""
64
+ google_auth = importlib.import_module("google.auth")
65
+ request_cls = importlib.import_module("google.auth.transport.requests").Request
66
+
67
+ scopes = (
68
+ [scope]
69
+ if scope and scope.startswith("http")
70
+ else ["https://www.googleapis.com/auth/cloud-platform"]
71
+ )
72
+ creds, _ = google_auth.default(scopes=scopes)
73
+ creds.refresh(request_cls())
74
+ return creds.token
@@ -0,0 +1,39 @@
1
+ """Dispatcher: turn a declarative :class:`TargetSpec` into a runnable ``@task``."""
2
+
3
+ import typing as t
4
+
5
+ from dreadnode.airt.targets.http import http_target
6
+ from dreadnode.airt.targets.spec import TargetSpec
7
+ from dreadnode.airt.targets.streaming.nova_sonic import nova_sonic_target
8
+ from dreadnode.core.task import Task
9
+
10
+
11
+ def build_target(spec: TargetSpec) -> Task[..., t.Any]:
12
+ """Build a dreadnode ``@task`` target from a :class:`TargetSpec`.
13
+
14
+ Example (HTTP, Azure AI Foundry)::
15
+
16
+ target = build_target(TargetSpec(
17
+ endpoint="https://my.westus.inference.ml.azure.com/score",
18
+ auth=TargetAuth(type="api_key", header="Authorization", value_prefix="Bearer ",
19
+ env_var="AZURE_FOUNDRY_KEY"),
20
+ request_template='{"input_data": {"input_string": ["{prompt}"]}}',
21
+ response_text_path="$.output",
22
+ ))
23
+
24
+ Example (streaming, Amazon Nova Sonic S2S)::
25
+
26
+ target = build_target(TargetSpec(
27
+ transport="streaming", protocol="nova_sonic", endpoint="us-east-1",
28
+ options={"voice": "matthew"},
29
+ ))
30
+ """
31
+ if spec.transport == "http":
32
+ return http_target(spec)
33
+ if spec.transport == "streaming":
34
+ if spec.protocol == "nova_sonic":
35
+ return nova_sonic_target(
36
+ region=spec.endpoint or "us-east-1", name=spec.name, **spec.options
37
+ )
38
+ raise ValueError(f"Unknown streaming protocol: {spec.protocol!r}")
39
+ raise ValueError(f"Unknown transport: {spec.transport!r}")
@@ -0,0 +1,45 @@
1
+ """HTTP request/response transport: declarative body template + JSONPath response."""
2
+
3
+ import json
4
+
5
+ import httpx
6
+
7
+ from dreadnode.airt.targets.auth import apply_auth
8
+ from dreadnode.airt.targets.message import extract_parts, extract_response_text
9
+ from dreadnode.airt.targets.spec import TargetSpec
10
+ from dreadnode.core.task import Task, task
11
+ from dreadnode.generators.message import Message
12
+
13
+
14
+ def _render_body(template: str, parts: dict[str, str]) -> dict:
15
+ body_str = template
16
+ for key, value in parts.items():
17
+ token = "{" + key + "}"
18
+ # JSON-escape the (untrusted) prompt; base64 is already safe.
19
+ replacement = json.dumps(value)[1:-1] if key == "prompt" else value
20
+ body_str = body_str.replace(token, replacement)
21
+ return json.loads(body_str)
22
+
23
+
24
+ async def http_call(message: Message, spec: TargetSpec) -> str:
25
+ """Serialize the message, POST it to the endpoint with auth, and extract the reply.
26
+
27
+ Kept free of the ``@task`` wrapper so the request/response logic is unit testable
28
+ without the tracing/storage a Task invocation requires.
29
+ """
30
+ body = _render_body(spec.request_template, extract_parts(message))
31
+ content = json.dumps(body).encode("utf-8")
32
+ headers = apply_auth(spec, {"Content-Type": "application/json"}, spec.endpoint, content)
33
+
34
+ async with httpx.AsyncClient(timeout=spec.timeout_s) as client:
35
+ resp = await client.post(spec.endpoint, content=content, headers=headers)
36
+ resp.raise_for_status()
37
+ data = resp.json()
38
+ return extract_response_text(data, spec.response_text_path)
39
+
40
+
41
+ def http_target(spec: TargetSpec) -> Task[..., str]:
42
+ async def target(message: Message) -> str:
43
+ return await http_call(message, spec)
44
+
45
+ return task(target, name=spec.name)