dreadnode 2.0.34__tar.gz → 2.0.36__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 (713) hide show
  1. {dreadnode-2.0.34 → dreadnode-2.0.36}/PKG-INFO +8 -5
  2. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/agents/agent.py +35 -1
  3. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/__init__.py +79 -0
  4. dreadnode-2.0.36/dreadnode/airt/_base.py +213 -0
  5. dreadnode-2.0.36/dreadnode/airt/art_engine.py +183 -0
  6. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/assessment.py +11 -1
  7. dreadnode-2.0.36/dreadnode/airt/atlas/__init__.py +352 -0
  8. dreadnode-2.0.36/dreadnode/airt/atlas/defense.py +260 -0
  9. dreadnode-2.0.36/dreadnode/airt/atlas/failure.py +347 -0
  10. dreadnode-2.0.36/dreadnode/airt/atlas/gate.py +245 -0
  11. dreadnode-2.0.36/dreadnode/airt/atlas/memory.py +144 -0
  12. dreadnode-2.0.36/dreadnode/airt/atlas/modes.py +109 -0
  13. dreadnode-2.0.36/dreadnode/airt/atlas/probes.py +154 -0
  14. dreadnode-2.0.36/dreadnode/airt/atlas/recon.py +238 -0
  15. dreadnode-2.0.36/dreadnode/airt/atlas/router.py +199 -0
  16. dreadnode-2.0.36/dreadnode/airt/atlas/strategy.py +875 -0
  17. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/crescendo.py +8 -4
  18. dreadnode-2.0.36/dreadnode/airt/evasion/__init__.py +46 -0
  19. dreadnode-2.0.36/dreadnode/airt/evasion/_base.py +399 -0
  20. dreadnode-2.0.36/dreadnode/airt/evasion/_text_common.py +198 -0
  21. dreadnode-2.0.36/dreadnode/airt/evasion/bae.py +62 -0
  22. dreadnode-2.0.36/dreadnode/airt/evasion/boundary.py +57 -0
  23. dreadnode-2.0.36/dreadnode/airt/evasion/deepwordbug.py +72 -0
  24. dreadnode-2.0.36/dreadnode/airt/evasion/hopskipjump.py +86 -0
  25. dreadnode-2.0.36/dreadnode/airt/evasion/pwws.py +112 -0
  26. dreadnode-2.0.36/dreadnode/airt/evasion/simba.py +67 -0
  27. dreadnode-2.0.36/dreadnode/airt/evasion/square.py +73 -0
  28. dreadnode-2.0.36/dreadnode/airt/evasion/text.py +90 -0
  29. dreadnode-2.0.36/dreadnode/airt/evasion/textbugger.py +69 -0
  30. dreadnode-2.0.36/dreadnode/airt/evasion/textfooler.py +48 -0
  31. dreadnode-2.0.36/dreadnode/airt/evasion/zoo.py +83 -0
  32. dreadnode-2.0.36/dreadnode/airt/extraction/__init__.py +63 -0
  33. dreadnode-2.0.36/dreadnode/airt/extraction/_base.py +703 -0
  34. dreadnode-2.0.36/dreadnode/airt/extraction/activethief.py +108 -0
  35. dreadnode-2.0.36/dreadnode/airt/extraction/copycat.py +32 -0
  36. dreadnode-2.0.36/dreadnode/airt/extraction/distillation.py +35 -0
  37. dreadnode-2.0.36/dreadnode/airt/extraction/equation_solving.py +34 -0
  38. dreadnode-2.0.36/dreadnode/airt/extraction/jacobian.py +82 -0
  39. dreadnode-2.0.36/dreadnode/airt/extraction/knockoff.py +34 -0
  40. dreadnode-2.0.36/dreadnode/airt/inversion/__init__.py +32 -0
  41. dreadnode-2.0.36/dreadnode/airt/inversion/_base.py +262 -0
  42. dreadnode-2.0.36/dreadnode/airt/inversion/confidence.py +80 -0
  43. dreadnode-2.0.36/dreadnode/airt/inversion/nes_inversion.py +100 -0
  44. dreadnode-2.0.36/dreadnode/airt/membership/__init__.py +59 -0
  45. dreadnode-2.0.36/dreadnode/airt/membership/_base.py +416 -0
  46. dreadnode-2.0.36/dreadnode/airt/membership/entropy.py +30 -0
  47. dreadnode-2.0.36/dreadnode/airt/membership/label_only.py +86 -0
  48. dreadnode-2.0.36/dreadnode/airt/membership/lira.py +83 -0
  49. dreadnode-2.0.36/dreadnode/airt/membership/loss.py +30 -0
  50. dreadnode-2.0.36/dreadnode/airt/membership/shadow_model.py +85 -0
  51. dreadnode-2.0.36/dreadnode/airt/membership/threshold.py +148 -0
  52. dreadnode-2.0.36/dreadnode/airt/model_export.py +129 -0
  53. dreadnode-2.0.36/dreadnode/airt/target.py +193 -0
  54. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/targets/__init__.py +12 -0
  55. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/targets/http.py +9 -4
  56. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/targets/message.py +14 -0
  57. dreadnode-2.0.36/dreadnode/airt/targets/prediction.py +211 -0
  58. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/targets/spec.py +9 -0
  59. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/targets/streaming/nova_sonic.py +9 -5
  60. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/api/models.py +24 -1
  61. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/airt.py +291 -5
  62. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/args.py +8 -0
  63. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/capability.py +18 -5
  64. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/evaluation.py +91 -0
  65. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/main.py +2 -0
  66. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/client/managed_client.py +2 -0
  67. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/client/models.py +2 -0
  68. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/client/runtime_client.py +63 -9
  69. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/main.py +18 -0
  70. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/print_mode.py +7 -1
  71. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/server/app.py +147 -11
  72. dreadnode-2.0.36/dreadnode/app/server/auth.py +120 -0
  73. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/server/capability_manager.py +50 -1
  74. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/server/runtime_events.py +7 -1
  75. dreadnode-2.0.36/dreadnode/app/server/runtime_token.py +395 -0
  76. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/server/session_hydrator.py +44 -0
  77. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/server/websocket.py +192 -21
  78. dreadnode-2.0.36/dreadnode/app/server/ws_auth.py +111 -0
  79. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/app.py +87 -2
  80. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/screens/capabilities.py +15 -2
  81. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/screens/models.py +5 -0
  82. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/screens/sessions.py +4 -4
  83. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/sessions_manager.py +97 -5
  84. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/turn_coordinator.py +14 -0
  85. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/conversation.py +38 -1
  86. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/tool.py +21 -3
  87. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/agent-output.md +5 -0
  88. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/dependencies-and-checks.md +3 -3
  89. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/hooks.md +20 -1
  90. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/policies.md +21 -0
  91. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/tools.md +21 -0
  92. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/sdk/capabilities.md +1 -0
  93. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/tui/default-tools.md +11 -0
  94. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/airt.md +26 -0
  95. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/evaluation.md +5 -0
  96. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/credits.md +1 -1
  97. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/capabilities/install.py +79 -11
  98. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/capabilities/loader.py +404 -46
  99. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/environment.py +10 -1
  100. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/generators/proxy.py +57 -0
  101. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/optimization/study.py +75 -6
  102. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/judge.py +15 -4
  103. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tracing/constants.py +32 -0
  104. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/audio.py +4 -4
  105. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/language.py +18 -9
  106. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/refine.py +9 -4
  107. {dreadnode-2.0.34 → dreadnode-2.0.36}/pyproject.toml +38 -10
  108. dreadnode-2.0.34/dreadnode/app/server/auth.py +0 -66
  109. dreadnode-2.0.34/dreadnode/app/server/ws_auth.py +0 -76
  110. {dreadnode-2.0.34 → dreadnode-2.0.36}/.gitignore +0 -0
  111. {dreadnode-2.0.34 → dreadnode-2.0.36}/LICENSE +0 -0
  112. {dreadnode-2.0.34 → dreadnode-2.0.36}/README.md +0 -0
  113. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/__init__.py +0 -0
  114. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/__main__.py +0 -0
  115. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/agents/__init__.py +0 -0
  116. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/agents/engines/AGENTS.md +0 -0
  117. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/agents/engines/__init__.py +0 -0
  118. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/agents/engines/base.py +0 -0
  119. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/agents/engines/claude_code.py +0 -0
  120. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/agents/engines/native.py +0 -0
  121. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/agents/events.py +0 -0
  122. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/agents/exceptions.py +0 -0
  123. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/agents/format.py +0 -0
  124. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/agents/hooks.py +0 -0
  125. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/agents/judge.py +0 -0
  126. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/agents/mcp/__init__.py +0 -0
  127. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/agents/mcp/auth.py +0 -0
  128. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/agents/mcp/client.py +0 -0
  129. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/agents/mcp/config.py +0 -0
  130. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/agents/mcp/server.py +0 -0
  131. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/agents/process_judge.py +0 -0
  132. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/agents/reactions.py +0 -0
  133. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/agents/sanitize.py +0 -0
  134. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/agents/skills.py +0 -0
  135. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/agents/stopping.py +0 -0
  136. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/agents/subagent.py +0 -0
  137. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/agents/tool_resolution.py +0 -0
  138. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/agents/tools.py +0 -0
  139. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/agents/trajectory.py +0 -0
  140. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/adversarial_reasoning.py +0 -0
  141. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/advpromptier.py +0 -0
  142. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/alignment_faking.py +0 -0
  143. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/analogy_escalation.py +0 -0
  144. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/analytics/__init__.py +0 -0
  145. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/analytics/aggregator.py +0 -0
  146. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/analytics/classifier.py +0 -0
  147. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/analytics/compliance.py +0 -0
  148. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/analytics/engine.py +0 -0
  149. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/analytics/recommendations.py +0 -0
  150. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/analytics/types.py +0 -0
  151. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/aprt_progressive.py +0 -0
  152. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/attention_shifting.py +0 -0
  153. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/autodan_turbo.py +0 -0
  154. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/autoredteamer.py +0 -0
  155. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/beast.py +0 -0
  156. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/compliance/__init__.py +0 -0
  157. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/compliance/atlas.py +0 -0
  158. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/compliance/nist.py +0 -0
  159. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/compliance/owasp.py +0 -0
  160. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/compliance/owasp_agentic.py +0 -0
  161. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/compliance/saif.py +0 -0
  162. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/constants.py +0 -0
  163. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/cot_jailbreak.py +0 -0
  164. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/data/__init__.py +0 -0
  165. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/data/assets/audio/adversarial_query.mp3 +0 -0
  166. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/data/assets/image/bomb.jpg +0 -0
  167. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/data/assets/image/meth.png +0 -0
  168. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/data/prompts/adversarial_benchmark_subset.csv +0 -0
  169. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/data/prompts/ai_safety.csv +0 -0
  170. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/data/rubrics/data_exfiltration.yaml +0 -0
  171. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/data/rubrics/goal_hijacking.yaml +0 -0
  172. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/data/rubrics/idor.yaml +0 -0
  173. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/data/rubrics/memory_poisoning.yaml +0 -0
  174. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/data/rubrics/privilege_escalation.yaml +0 -0
  175. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/data/rubrics/rce.yaml +0 -0
  176. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/data/rubrics/scope_creep.yaml +0 -0
  177. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/data/rubrics/tool_chaining.yaml +0 -0
  178. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/data/rubrics/tool_selection_safety.yaml +0 -0
  179. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/data/rubrics/unbounded_agency.yaml +0 -0
  180. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/data/rubrics/web_chatbot_security.yaml +0 -0
  181. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/data/templates/crescendo/variant_1.yaml +0 -0
  182. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/data/templates/crescendo/variant_2.yaml +0 -0
  183. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/data/templates/crescendo/variant_3.yaml +0 -0
  184. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/data/templates/crescendo/variant_4.yaml +0 -0
  185. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/data/templates/crescendo/variant_5.yaml +0 -0
  186. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/deep_inception.py +0 -0
  187. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/drattack.py +0 -0
  188. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/echo_chamber.py +0 -0
  189. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/events.py +0 -0
  190. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/genetic_persona.py +0 -0
  191. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/goat.py +0 -0
  192. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/goat_v2.py +0 -0
  193. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/gptfuzzer.py +0 -0
  194. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/humor_bypass.py +0 -0
  195. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/image.py +0 -0
  196. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/j2_meta.py +0 -0
  197. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/jbdistill.py +0 -0
  198. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/jbfuzz.py +0 -0
  199. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/lrm_autonomous.py +0 -0
  200. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/mapf.py +0 -0
  201. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/message_parts.py +0 -0
  202. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/multimodal.py +0 -0
  203. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/nexus.py +0 -0
  204. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/pair.py +0 -0
  205. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/persona_hijack.py +0 -0
  206. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/prompt.py +0 -0
  207. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/quantization_safety.py +0 -0
  208. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/rainbow.py +0 -0
  209. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/refusal_aware.py +0 -0
  210. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/renellm.py +0 -0
  211. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/reporting/__init__.py +0 -0
  212. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/reporting/json_report.py +0 -0
  213. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/reporting/llm_summary.py +0 -0
  214. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/reporting/markdown.py +0 -0
  215. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/reward_hacking.py +0 -0
  216. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/salami_slicing.py +0 -0
  217. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/self_persuasion.py +0 -0
  218. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/siren.py +0 -0
  219. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/tap.py +0 -0
  220. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/targets/auth.py +0 -0
  221. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/targets/factory.py +0 -0
  222. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/targets/streaming/__init__.py +0 -0
  223. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/templatefuzz.py +0 -0
  224. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/tmap_trajectory.py +0 -0
  225. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/trojail.py +0 -0
  226. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/airt/watermark_removal.py +0 -0
  227. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/__init__.py +0 -0
  228. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/api/__init__.py +0 -0
  229. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/api/client.py +0 -0
  230. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/__init__.py +0 -0
  231. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/dataset.py +0 -0
  232. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/environment.py +0 -0
  233. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/inference_model.py +0 -0
  234. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/judge.py +0 -0
  235. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/model.py +0 -0
  236. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/optimize.py +0 -0
  237. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/runtime.py +0 -0
  238. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/sandbox.py +0 -0
  239. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/secret.py +0 -0
  240. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/session.py +0 -0
  241. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/shared.py +0 -0
  242. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/task.py +0 -0
  243. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/task_set.py +0 -0
  244. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/templates/__init__.py +0 -0
  245. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/templates/init/__init__.py +0 -0
  246. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/templates/init/challenge/Dockerfile +0 -0
  247. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/templates/init/docker-compose.yaml +0 -0
  248. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/templates/init/provision.sh +0 -0
  249. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/templates/init/solution.sh +0 -0
  250. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/templates/init/task-remote.yaml.tmpl +0 -0
  251. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/templates/init/task.yaml.tmpl +0 -0
  252. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/templates/init/teardown.sh +0 -0
  253. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/templates/init/verify.sh +0 -0
  254. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/train.py +0 -0
  255. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/cli/worlds.py +0 -0
  256. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/client/__init__.py +0 -0
  257. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/client/interactive.py +0 -0
  258. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/client/transports.py +0 -0
  259. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/config.py +0 -0
  260. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/env.py +0 -0
  261. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/model_catalog.py +0 -0
  262. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/paths.py +0 -0
  263. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/server/__init__.py +0 -0
  264. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/server/model_resolution.py +0 -0
  265. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/server/prompt.py +0 -0
  266. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/server/prompt_registry.py +0 -0
  267. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/server/session_persistence.py +0 -0
  268. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/server/turn_coordinator.py +0 -0
  269. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/server/utils.py +0 -0
  270. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/server/worker_manager.py +0 -0
  271. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/__init__.py +0 -0
  272. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/auth_flow.py +0 -0
  273. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/capabilities_manager.py +0 -0
  274. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/command_dispatcher.py +0 -0
  275. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/commands.py +0 -0
  276. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/connection.py +0 -0
  277. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/dreadnode.tcss +0 -0
  278. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/error_handler.py +0 -0
  279. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/model_manager.py +0 -0
  280. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/model_variants.py +0 -0
  281. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/profile_manager.py +0 -0
  282. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/runtime_cache.py +0 -0
  283. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/screen_router.py +0 -0
  284. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/screens/__init__.py +0 -0
  285. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/screens/auth.py +0 -0
  286. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/screens/base.py +0 -0
  287. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/screens/capability_docs.py +0 -0
  288. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/screens/connection_error.py +0 -0
  289. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/screens/console.py +0 -0
  290. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/screens/environments.py +0 -0
  291. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/screens/evaluations.py +0 -0
  292. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/screens/raw_spans.py +0 -0
  293. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/screens/readme.py +0 -0
  294. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/screens/runtimes.py +0 -0
  295. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/screens/sandboxes.py +0 -0
  296. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/screens/secrets.py +0 -0
  297. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/screens/services.py +0 -0
  298. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/screens/theme_showcase.py +0 -0
  299. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/screens/traces.py +0 -0
  300. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/screens/workspaces.py +0 -0
  301. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/spans_reader.py +0 -0
  302. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/status_messages.py +0 -0
  303. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/theme.py +0 -0
  304. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/tool_format.py +0 -0
  305. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/turn_lifecycle.py +0 -0
  306. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/turn_reducer.py +0 -0
  307. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/turn_state_phase.py +0 -0
  308. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/update_check.py +0 -0
  309. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/__init__.py +0 -0
  310. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/agent_dialog.py +0 -0
  311. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/agent_suggester.py +0 -0
  312. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/composer.py +0 -0
  313. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/confirm_modal.py +0 -0
  314. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/context_bar.py +0 -0
  315. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/flash.py +0 -0
  316. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/header_bar.py +0 -0
  317. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/help_panel.py +0 -0
  318. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/human_prompt.py +0 -0
  319. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/mention_overlay.py +0 -0
  320. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/message_queue.py +0 -0
  321. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/new_messages_pill.py +0 -0
  322. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/overlay_mixin.py +0 -0
  323. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/permission_prompt.py +0 -0
  324. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/profile_dialog.py +0 -0
  325. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/prompt_info.py +0 -0
  326. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/rewind_picker.py +0 -0
  327. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/session_sidebar.py +0 -0
  328. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/skills_dialog.py +0 -0
  329. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/slash_overlay.py +0 -0
  330. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/status_bar.py +0 -0
  331. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/throbber.py +0 -0
  332. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/tool_progress.py +0 -0
  333. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/tools_dialog.py +0 -0
  334. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/welcome.py +0 -0
  335. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/widgets/whoami.py +0 -0
  336. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/app/tui/wire_events.py +0 -0
  337. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/__init__.py +0 -0
  338. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/MAINTAINING.md +0 -0
  339. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/agents/dreadnode.md +0 -0
  340. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/capability.yaml +0 -0
  341. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/SKILL.md +0 -0
  342. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/capability-improvement.md +0 -0
  343. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/methodology-grounding.md +0 -0
  344. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/prior-art-audit.md +0 -0
  345. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/promoting-capabilities.md +0 -0
  346. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/quality-bar.md +0 -0
  347. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/INDEX.md +0 -0
  348. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/agents.md +0 -0
  349. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/custom-engines.md +0 -0
  350. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/engines.md +0 -0
  351. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/env-vars.md +0 -0
  352. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/events.md +0 -0
  353. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/flags.md +0 -0
  354. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/installing.md +0 -0
  355. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/manifest.md +0 -0
  356. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/mcp-servers.md +0 -0
  357. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/overview.md +0 -0
  358. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/publishing.md +0 -0
  359. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/quickstart.md +0 -0
  360. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/skills.md +0 -0
  361. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/workers-reference.md +0 -0
  362. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/workers.md +0 -0
  363. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/writing-skills.md +0 -0
  364. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/sdk/agents.md +0 -0
  365. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references-and-depth.md +0 -0
  366. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/runtime-default-capability.md +0 -0
  367. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/SKILL.md +0 -0
  368. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/INDEX.md +0 -0
  369. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/capability.md +0 -0
  370. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/dataset.md +0 -0
  371. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/env.md +0 -0
  372. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/inference-model.md +0 -0
  373. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/main.md +0 -0
  374. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/model.md +0 -0
  375. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/optimize.md +0 -0
  376. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/overview.md +0 -0
  377. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/runtime.md +0 -0
  378. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/sandbox.md +0 -0
  379. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/secret.md +0 -0
  380. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/task-set.md +0 -0
  381. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/task.md +0 -0
  382. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/train.md +0 -0
  383. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/worlds.md +0 -0
  384. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/getting-started/authentication.md +0 -0
  385. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/SKILL.md +0 -0
  386. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/INDEX.md +0 -0
  387. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/capabilities/installing.md +0 -0
  388. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/capabilities/overview.md +0 -0
  389. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/getting-started/authentication.md +0 -0
  390. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/getting-started/overview.md +0 -0
  391. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/getting-started/quickstart.md +0 -0
  392. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/chat-models.md +0 -0
  393. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/organizations.md +0 -0
  394. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/overview.md +0 -0
  395. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/projects.md +0 -0
  396. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/secrets.md +0 -0
  397. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/settings.md +0 -0
  398. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/workspaces.md +0 -0
  399. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/configuration.md +0 -0
  400. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/managing.md +0 -0
  401. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/manifest-reference.md +0 -0
  402. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/overview.md +0 -0
  403. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/quickstart.md +0 -0
  404. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/serve.md +0 -0
  405. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/sandboxes/environment-lifecycle.md +0 -0
  406. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/sandboxes/inspecting.md +0 -0
  407. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/sandboxes/overview.md +0 -0
  408. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/sandboxes/runtime-limits.md +0 -0
  409. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/getting-started/SKILL.md +0 -0
  410. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/dreadnode/skills/research-capabilities/SKILL.md +0 -0
  411. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/self-improvement/.gitignore +0 -0
  412. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/self-improvement/capability.yaml +0 -0
  413. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/self-improvement/hooks/__init__.py +0 -0
  414. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/self-improvement/hooks/observer.py +0 -0
  415. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/__init__.py +0 -0
  416. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/classifier.py +0 -0
  417. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/reflector_goal.py +0 -0
  418. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/skill_io.py +0 -0
  419. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/self-improvement/skills-promoted/.gitkeep +0 -0
  420. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/self-improvement/skills-proposed/.gitkeep +0 -0
  421. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/self-improvement/tools/__init__.py +0 -0
  422. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/self-improvement/tools/reflector.py +0 -0
  423. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/builtin_capabilities/self-improvement/tools/skill_stats.py +0 -0
  424. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/capabilities/__init__.py +0 -0
  425. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/capabilities/capability.py +0 -0
  426. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/capabilities/flags.py +0 -0
  427. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/capabilities/sync.py +0 -0
  428. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/capabilities/tool_rules.py +0 -0
  429. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/capabilities/types.py +0 -0
  430. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/capabilities/worker.py +0 -0
  431. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/capabilities/worker_runner.py +0 -0
  432. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/__init__.py +0 -0
  433. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/conditions.py +0 -0
  434. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/discovery.py +0 -0
  435. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/exceptions.py +0 -0
  436. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/execution.py +0 -0
  437. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/hook.py +0 -0
  438. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/judge.py +0 -0
  439. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/load.py +0 -0
  440. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/log.py +0 -0
  441. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/meta/__init__.py +0 -0
  442. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/meta/config.py +0 -0
  443. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/meta/context.py +0 -0
  444. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/meta/hydrate.py +0 -0
  445. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/meta/introspect.py +0 -0
  446. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/metric.py +0 -0
  447. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/object.py +0 -0
  448. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/scorer.py +0 -0
  449. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/serialization.py +0 -0
  450. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/stopping.py +0 -0
  451. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/task.py +0 -0
  452. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/templating.py +0 -0
  453. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/transforms.py +0 -0
  454. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/types/__init__.py +0 -0
  455. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/types/audio.py +0 -0
  456. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/types/base.py +0 -0
  457. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/types/common.py +0 -0
  458. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/types/image.py +0 -0
  459. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/types/object_3d.py +0 -0
  460. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/types/table.py +0 -0
  461. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/types/text.py +0 -0
  462. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/types/video.py +0 -0
  463. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/core/util.py +0 -0
  464. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/datasets/__init__.py +0 -0
  465. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/datasets/dataset.py +0 -0
  466. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/datasets/hf.py +0 -0
  467. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/datasets/local.py +0 -0
  468. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/evaluations/__init__.py +0 -0
  469. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/evaluations/console.py +0 -0
  470. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/evaluations/evaluation.py +0 -0
  471. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/evaluations/events.py +0 -0
  472. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/evaluations/format.py +0 -0
  473. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/evaluations/result.py +0 -0
  474. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/evaluations/sample.py +0 -0
  475. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/generators/__init__.py +0 -0
  476. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/generators/caching.py +0 -0
  477. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/generators/chat.py +0 -0
  478. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/generators/data.py +0 -0
  479. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/generators/exceptions.py +0 -0
  480. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/generators/generator/__init__.py +0 -0
  481. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/generators/generator/base.py +0 -0
  482. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/generators/generator/http.py +0 -0
  483. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/generators/generator/litellm_.py +0 -0
  484. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/generators/generator/transformers_.py +0 -0
  485. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/generators/generator/vllm_.py +0 -0
  486. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/generators/message.py +0 -0
  487. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/generators/models.py +0 -0
  488. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/generators/parsing.py +0 -0
  489. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/generators/tokenizer/__init__.py +0 -0
  490. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/generators/tokenizer/base.py +0 -0
  491. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/generators/tokenizer/transformers_.py +0 -0
  492. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/generators/utils.py +0 -0
  493. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/items/__init__.py +0 -0
  494. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/items/config.py +0 -0
  495. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/items/models.py +0 -0
  496. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/judges/__init__.py +0 -0
  497. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/judges/outcome.py +0 -0
  498. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/judges/trajectory.py +0 -0
  499. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/judges/trajectory_tools.py +0 -0
  500. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/models/__init__.py +0 -0
  501. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/models/hf.py +0 -0
  502. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/models/local.py +0 -0
  503. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/models/model.py +0 -0
  504. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/optimization/__init__.py +0 -0
  505. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/optimization/adapters/__init__.py +0 -0
  506. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/optimization/adapters/_env_eval.py +0 -0
  507. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/optimization/adapters/agent.py +0 -0
  508. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/optimization/adapters/env.py +0 -0
  509. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/optimization/adapters/runtime.py +0 -0
  510. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/optimization/adapters/stack.py +0 -0
  511. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/optimization/api.py +0 -0
  512. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/optimization/backends/__init__.py +0 -0
  513. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/optimization/backends/base.py +0 -0
  514. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/optimization/backends/gepa.py +0 -0
  515. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/optimization/collectors.py +0 -0
  516. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/optimization/config.py +0 -0
  517. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/optimization/console.py +0 -0
  518. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/optimization/events.py +0 -0
  519. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/optimization/format.py +0 -0
  520. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/optimization/jobs.py +0 -0
  521. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/optimization/result.py +0 -0
  522. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/optimization/sampler.py +0 -0
  523. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/optimization/sampling.py +0 -0
  524. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/optimization/search.py +0 -0
  525. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/optimization/stopping.py +0 -0
  526. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/optimization/trial.py +0 -0
  527. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/packaging/__init__.py +0 -0
  528. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/packaging/loader.py +0 -0
  529. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/packaging/manifest.py +0 -0
  530. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/packaging/oci.py +0 -0
  531. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/packaging/package.py +0 -0
  532. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/packaging/task_validation.py +0 -0
  533. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/policies/__init__.py +0 -0
  534. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/policies/guard.py +0 -0
  535. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/policies/reconciliation.py +0 -0
  536. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/policies/rubrics/process/default.yaml +0 -0
  537. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/py.typed +0 -0
  538. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/samplers/__init__.py +0 -0
  539. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/samplers/boundary.py +0 -0
  540. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/samplers/fuzzing.py +0 -0
  541. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/samplers/graph.py +0 -0
  542. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/samplers/grid.py +0 -0
  543. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/samplers/image.py +0 -0
  544. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/samplers/mapelites.py +0 -0
  545. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/samplers/optuna.py +0 -0
  546. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/samplers/random.py +0 -0
  547. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/samplers/registry.py +0 -0
  548. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/samplers/strategy.py +0 -0
  549. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/__init__.py +0 -0
  550. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/advanced_jailbreak_detection.py +0 -0
  551. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/agent_security.py +0 -0
  552. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/agentic.py +0 -0
  553. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/agentic_workflow.py +0 -0
  554. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/attack_outcome.py +0 -0
  555. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/classification.py +0 -0
  556. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/consistency.py +0 -0
  557. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/contains.py +0 -0
  558. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/cosine_sim.py +0 -0
  559. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/credentials.py +0 -0
  560. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/crucible.py +0 -0
  561. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/documentation_security.py +0 -0
  562. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/exfiltration_detection.py +0 -0
  563. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/format.py +0 -0
  564. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/harm.py +0 -0
  565. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/ide_security.py +0 -0
  566. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/image.py +0 -0
  567. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/json.py +0 -0
  568. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/judge_ensemble.py +0 -0
  569. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/length.py +0 -0
  570. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/lexical.py +0 -0
  571. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/mcp_security.py +0 -0
  572. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/memorization.py +0 -0
  573. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/multi_agent_security.py +0 -0
  574. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/pii.py +0 -0
  575. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/prompt_leak.py +0 -0
  576. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/readability.py +0 -0
  577. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/reasoning_security.py +0 -0
  578. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/sentiment.py +0 -0
  579. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/similarity.py +0 -0
  580. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/structural_detection.py +0 -0
  581. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/scorers/supply_chain_detection.py +0 -0
  582. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/storage/__init__.py +0 -0
  583. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/storage/providers.py +0 -0
  584. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/storage/session_store.py +0 -0
  585. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/storage/storage.py +0 -0
  586. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tools/__init__.py +0 -0
  587. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tools/_ripgrep.py +0 -0
  588. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tools/apply_patch.py +0 -0
  589. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tools/dreadnode_cli.py +0 -0
  590. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tools/editing.py +0 -0
  591. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tools/execute.py +0 -0
  592. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tools/fetch.py +0 -0
  593. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tools/glob.py +0 -0
  594. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tools/grep.py +0 -0
  595. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tools/interaction.py +0 -0
  596. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tools/ls.py +0 -0
  597. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tools/memory.py +0 -0
  598. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tools/project_memory.py +0 -0
  599. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tools/read.py +0 -0
  600. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tools/report.py +0 -0
  601. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tools/report_items.py +0 -0
  602. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tools/task.py +0 -0
  603. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tools/think.py +0 -0
  604. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tools/todo.py +0 -0
  605. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tools/trajectory_search.py +0 -0
  606. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tools/web_extract.py +0 -0
  607. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tools/web_search.py +0 -0
  608. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tools/write.py +0 -0
  609. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tracing/__init__.py +0 -0
  610. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tracing/convert.py +0 -0
  611. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tracing/exporter.py +0 -0
  612. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tracing/exporters.py +0 -0
  613. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tracing/span.py +0 -0
  614. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tracing/spans.py +0 -0
  615. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/tracing/trace_converter.py +0 -0
  616. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/__init__.py +0 -0
  617. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/_progress.py +0 -0
  618. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/base.py +0 -0
  619. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/dpo.py +0 -0
  620. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/env_rollouts.py +0 -0
  621. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/etl/__init__.py +0 -0
  622. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/etl/_common.py +0 -0
  623. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/etl/rl.py +0 -0
  624. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/etl/sft.py +0 -0
  625. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/etl/worlds.py +0 -0
  626. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/events.py +0 -0
  627. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/grpo.py +0 -0
  628. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/jobs.py +0 -0
  629. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/models.py +0 -0
  630. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/ppo.py +0 -0
  631. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/prime.py +0 -0
  632. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/ray/__init__.py +0 -0
  633. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/ray/async_trainer.py +0 -0
  634. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/ray/config.py +0 -0
  635. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/ray/coordinator.py +0 -0
  636. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/ray/distributed.py +0 -0
  637. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/ray/dpo.py +0 -0
  638. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/ray/experience.py +0 -0
  639. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/ray/fsdp2_learner.py +0 -0
  640. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/ray/inference.py +0 -0
  641. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/ray/learner.py +0 -0
  642. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/ray/multi_turn.py +0 -0
  643. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/ray/ppo.py +0 -0
  644. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/ray/reward_model.py +0 -0
  645. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/ray/rollout_env.py +0 -0
  646. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/ray/rollout_worker.py +0 -0
  647. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/ray/sft.py +0 -0
  648. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/ray/trainer.py +0 -0
  649. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/recipes.py +0 -0
  650. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/rewards/__init__.py +0 -0
  651. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/rewards/aggregator.py +0 -0
  652. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/rewards/functions.py +0 -0
  653. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/rewards/scorer_bridge.py +0 -0
  654. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/rewards/shaping.py +0 -0
  655. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/rewards/types.py +0 -0
  656. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/rollouts/__init__.py +0 -0
  657. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/rollouts/adapters.py +0 -0
  658. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/rollouts/agent_rollout.py +0 -0
  659. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/rollouts/orchestrator.py +0 -0
  660. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/rollouts/types.py +0 -0
  661. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/rollouts/worlds.py +0 -0
  662. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/serving/__init__.py +0 -0
  663. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/serving/vllm_client.py +0 -0
  664. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/sft.py +0 -0
  665. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/tinker/__init__.py +0 -0
  666. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/tinker/config.py +0 -0
  667. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/tinker/data.py +0 -0
  668. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/tinker/renderer.py +0 -0
  669. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/tinker/rl.py +0 -0
  670. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/tinker/trainer.py +0 -0
  671. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/tinker_sft.py +0 -0
  672. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/training/utils.py +0 -0
  673. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/__init__.py +0 -0
  674. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/advanced_jailbreak.py +0 -0
  675. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/adversarial_suffix.py +0 -0
  676. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/agent_skill.py +0 -0
  677. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/agentic_workflow.py +0 -0
  678. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/backdoor_finetune.py +0 -0
  679. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/browser_agent_attacks.py +0 -0
  680. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/cipher.py +0 -0
  681. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/competitive_parity.py +0 -0
  682. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/constitutional.py +0 -0
  683. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/document.py +0 -0
  684. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/documentation_poison.py +0 -0
  685. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/encoding.py +0 -0
  686. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/exfiltration.py +0 -0
  687. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/flip_attack.py +0 -0
  688. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/guardrail_bypass.py +0 -0
  689. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/ide_injection.py +0 -0
  690. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/image.py +0 -0
  691. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/injection.py +0 -0
  692. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/json_tools.py +0 -0
  693. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/logic_bomb.py +0 -0
  694. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/mcp_attacks.py +0 -0
  695. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/multi_agent_attacks.py +0 -0
  696. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/multimodal_attacks.py +0 -0
  697. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/persuasion.py +0 -0
  698. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/perturbation.py +0 -0
  699. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/pii_extraction.py +0 -0
  700. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/pythonic_tools.py +0 -0
  701. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/rag_poisoning.py +0 -0
  702. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/reasoning_attacks.py +0 -0
  703. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/response_steering.py +0 -0
  704. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/structural_exploits.py +0 -0
  705. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/stylistic.py +0 -0
  706. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/substitution.py +0 -0
  707. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/supply_chain.py +0 -0
  708. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/swap.py +0 -0
  709. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/system_prompt_extraction.py +0 -0
  710. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/text.py +0 -0
  711. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/video.py +0 -0
  712. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/transforms/xml_tools.py +0 -0
  713. {dreadnode-2.0.34 → dreadnode-2.0.36}/dreadnode/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dreadnode
3
- Version: 2.0.34
3
+ Version: 2.0.36
4
4
  Summary: Dreadnode SDK
5
5
  Project-URL: Homepage, https://dreadnode.io
6
6
  Project-URL: Documentation, https://docs.dreadnode.io
@@ -9,6 +9,9 @@ License-File: LICENSE
9
9
  Requires-Python: <3.14,>=3.11
10
10
  Requires-Dist: aiofiles<25.0.0,>=24.1.0
11
11
  Requires-Dist: art<7.0.0,>=6.5
12
+ Requires-Dist: aws-sdk-bedrock-runtime>=0.7.0; python_version >= '3.12'
13
+ Requires-Dist: awscrt>=0.27.0; python_version >= '3.12'
14
+ Requires-Dist: boto3>=1.40.0
12
15
  Requires-Dist: coolname<3.0.0,>=2.2.0
13
16
  Requires-Dist: croniter<7.0.0,>=6.0.0
14
17
  Requires-Dist: cyclopts>=4.2.0
@@ -40,6 +43,7 @@ Requires-Dist: pydantic-xml>=2.14.0
40
43
  Requires-Dist: pydantic<3.0.0,>=2.9.2
41
44
  Requires-Dist: pyyaml>=6.0.2
42
45
  Requires-Dist: scipy<2.0.0,>=1.11.0
46
+ Requires-Dist: smithy-aws-core>=0.7.0; python_version >= '3.12'
43
47
  Requires-Dist: soundfile<1.0.0,>=0.13.1
44
48
  Requires-Dist: starlette<1.4.0,>=1.3.1
45
49
  Requires-Dist: textual>=8.0.2
@@ -47,6 +51,9 @@ Requires-Dist: transformers>=4.57.1
47
51
  Requires-Dist: uvicorn>=0.34.0
48
52
  Requires-Dist: websockets>=14.0
49
53
  Requires-Dist: xmltodict>=1.0.2
54
+ Provides-Extra: airt-ml
55
+ Requires-Dist: scikit-learn<2.0.0,>=1.7.1; extra == 'airt-ml'
56
+ Requires-Dist: torch>=2.9.0; extra == 'airt-ml'
50
57
  Provides-Extra: all
51
58
  Requires-Dist: confusables<2.0.0,>=1.2.0; extra == 'all'
52
59
  Requires-Dist: moviepy<3.0.0,>=2.1.2; extra == 'all'
@@ -63,10 +70,6 @@ Requires-Dist: torch>=2.9.0; extra == 'all'
63
70
  Provides-Extra: claude-code
64
71
  Requires-Dist: claude-agent-sdk>=0.1.0; extra == 'claude-code'
65
72
  Provides-Extra: nova-sonic
66
- Requires-Dist: aws-sdk-bedrock-runtime>=0.7.0; (python_version >= '3.12') and extra == 'nova-sonic'
67
- Requires-Dist: awscrt>=0.27.0; extra == 'nova-sonic'
68
- Requires-Dist: boto3>=1.40.0; extra == 'nova-sonic'
69
- Requires-Dist: smithy-aws-core>=0.7.0; (python_version >= '3.12') and extra == 'nova-sonic'
70
73
  Provides-Extra: scoring
71
74
  Requires-Dist: confusables<2.0.0,>=1.2.0; extra == 'scoring'
72
75
  Requires-Dist: nltk<4.0.0,>=3.9.1; extra == 'scoring'
@@ -133,6 +133,31 @@ def _is_transient_api_error(error: BaseException) -> bool:
133
133
  return False
134
134
 
135
135
 
136
+ def _replayable(messages: list[Message]) -> list[Message]:
137
+ """Drop assistant messages that carry nothing worth sending back.
138
+
139
+ A generation stopped by a content filter leaves an empty assistant message.
140
+ The trajectory keeps it — it is the record of what the provider did, and
141
+ the transcript renders a warning from it — but replaying it on the next
142
+ turn sends an empty text block, which some providers reject outright
143
+ (see ``CacheControlOnEmptyTextFixup``) and none can use (ENG-7585).
144
+
145
+ Reasoning lives in ``metadata``, not ``content``, so a thinking-only
146
+ message is still replayable and must survive this filter.
147
+ """
148
+
149
+ def carries_nothing(message: Message) -> bool:
150
+ return (
151
+ message.role == "assistant"
152
+ and not message.content
153
+ and not message.tool_calls
154
+ and not message.metadata.get("reasoning_content")
155
+ and not message.metadata.get("thinking_blocks")
156
+ )
157
+
158
+ return [message for message in messages if not carries_nothing(message)]
159
+
160
+
136
161
  class Agent(Executor[AgentEvent, Trajectory]):
137
162
  """
138
163
  Agent abstraction for applying tools, event logic, and message state to LLM generation.
@@ -776,7 +801,7 @@ class Agent(Executor[AgentEvent, Trajectory]):
776
801
  """
777
802
  traj = trajectory if trajectory is not None else self.trajectory
778
803
  messages = [
779
- *deepcopy(traj.messages),
804
+ *_replayable(deepcopy(traj.messages)),
780
805
  Message(
781
806
  "user",
782
807
  str(self._current_input),
@@ -925,6 +950,15 @@ class Agent(Executor[AgentEvent, Trajectory]):
925
950
  break
926
951
 
927
952
  step_chat.generated[-1].metadata.update(step_chat.extra)
953
+ # The provider's stop reason belongs to the assistant
954
+ # message, not to a particular event stream — stamping it
955
+ # here (before any event is dispatched) lets hooks,
956
+ # transcript reloads and non-live consumers all recover the
957
+ # same outcome live GenerationEnd observers see (ENG-7585).
958
+ if step_chat.stop_reason:
959
+ step_chat.generated[-1].metadata["generation_stop_reason"] = (
960
+ step_chat.stop_reason
961
+ )
928
962
  for msg in step_chat.generated:
929
963
  msg.metadata.setdefault("agent", self.name)
930
964
  msg.metadata.setdefault("model", self.model_name)
@@ -54,6 +54,16 @@ Image adversarial attacks:
54
54
 
55
55
  Multimodal attacks:
56
56
  - multimodal_attack: Transform-based multimodal probing (vision, audio, text)
57
+
58
+ Traditional-ML attacks (query a classifier predict API via PredictionTargetSpec):
59
+ - equation_solving_extraction: linear-model weight recovery (Tramèr'16)
60
+ - jacobian_extraction: Jacobian dataset augmentation (Papernot'17)
61
+ - copycat_extraction: hard-label distillation (CopycatCNN)
62
+ - knockoff_extraction: soft-label transfer-set extraction (Knockoff Nets)
63
+ - threshold_membership: confidence/entropy/loss-threshold membership inference (Yeom'18)
64
+ - label_only_membership: label-only membership inference (Choquette-Choo'21)
65
+ - confidence_inversion: MI-Face confidence-maximizing model inversion (Fredrikson'15)
66
+ - nes_inversion: NES-based confidence-maximizing model inversion
57
67
  """
58
68
 
59
69
  from dreadnode.airt.adversarial_reasoning import adversarial_reasoning_attack
@@ -62,6 +72,7 @@ from dreadnode.airt.alignment_faking import alignment_faking_attack
62
72
  from dreadnode.airt.analogy_escalation import analogy_escalation_attack
63
73
  from dreadnode.airt.aprt_progressive import aprt_progressive_attack
64
74
  from dreadnode.airt.assessment import Assessment
75
+ from dreadnode.airt.atlas import atlas_attack
65
76
  from dreadnode.airt.attention_shifting import attention_shifting_attack
66
77
  from dreadnode.airt.autodan_turbo import autodan_turbo_attack
67
78
  from dreadnode.airt.autoredteamer import autoredteamer_attack
@@ -71,6 +82,27 @@ from dreadnode.airt.crescendo import crescendo_attack
71
82
  from dreadnode.airt.deep_inception import deep_inception_attack
72
83
  from dreadnode.airt.drattack import drattack
73
84
  from dreadnode.airt.echo_chamber import echo_chamber_attack
85
+ from dreadnode.airt.evasion import (
86
+ bae_evasion,
87
+ boundary_evasion,
88
+ deepwordbug_evasion,
89
+ hopskipjump_evasion,
90
+ pwws_evasion,
91
+ simba_evasion,
92
+ square_evasion,
93
+ text_evasion,
94
+ textbugger_evasion,
95
+ textfooler_evasion,
96
+ zoo_evasion,
97
+ )
98
+ from dreadnode.airt.extraction import (
99
+ activethief_extraction,
100
+ copycat_extraction,
101
+ distillation_extraction,
102
+ equation_solving_extraction,
103
+ jacobian_extraction,
104
+ knockoff_extraction,
105
+ )
74
106
  from dreadnode.airt.genetic_persona import genetic_persona_attack
75
107
  from dreadnode.airt.goat import goat_attack
76
108
  from dreadnode.airt.goat_v2 import goat_v2_attack
@@ -82,11 +114,23 @@ from dreadnode.airt.image import (
82
114
  simba_attack,
83
115
  zoo_attack,
84
116
  )
117
+ from dreadnode.airt.inversion import (
118
+ confidence_inversion,
119
+ nes_inversion,
120
+ )
85
121
  from dreadnode.airt.j2_meta import j2_meta_attack
86
122
  from dreadnode.airt.jbdistill import jbdistill_attack
87
123
  from dreadnode.airt.jbfuzz import jbfuzz_attack
88
124
  from dreadnode.airt.lrm_autonomous import lrm_autonomous_attack
89
125
  from dreadnode.airt.mapf import mapf_attack
126
+ from dreadnode.airt.membership import (
127
+ entropy_membership,
128
+ label_only_membership,
129
+ lira_membership,
130
+ loss_membership,
131
+ shadow_model_membership,
132
+ threshold_membership,
133
+ )
90
134
  from dreadnode.airt.multimodal import multimodal_attack
91
135
  from dreadnode.airt.nexus import nexus_attack
92
136
  from dreadnode.airt.pair import pair_attack
@@ -101,9 +145,13 @@ from dreadnode.airt.salami_slicing import salami_slicing_attack
101
145
  from dreadnode.airt.self_persuasion import self_persuasion_attack
102
146
  from dreadnode.airt.siren import siren_attack
103
147
  from dreadnode.airt.tap import tap_attack
148
+ from dreadnode.airt.target import extract_response_text, extract_tool_calls
104
149
  from dreadnode.airt.targets import (
150
+ Prediction,
151
+ PredictionTargetSpec,
105
152
  TargetAuth,
106
153
  TargetSpec,
154
+ build_prediction_target,
107
155
  build_target,
108
156
  nova_sonic_target,
109
157
  )
@@ -114,41 +162,64 @@ from dreadnode.airt.watermark_removal import watermark_removal_attack
114
162
 
115
163
  __all__ = [
116
164
  "Assessment",
165
+ "Prediction",
166
+ "PredictionTargetSpec",
117
167
  "TargetAuth",
118
168
  "TargetSpec",
169
+ "activethief_extraction",
119
170
  "adversarial_reasoning_attack",
120
171
  "advpromptier_attack",
121
172
  "alignment_faking_attack",
122
173
  "analogy_escalation_attack",
123
174
  "aprt_progressive_attack",
175
+ "atlas_attack",
124
176
  "attention_shifting_attack",
125
177
  "autodan_turbo_attack",
126
178
  "autoredteamer_attack",
179
+ "bae_evasion",
127
180
  "beast_attack",
181
+ "boundary_evasion",
182
+ "build_prediction_target",
128
183
  "build_target",
184
+ "confidence_inversion",
185
+ "copycat_extraction",
129
186
  "cot_jailbreak_attack",
130
187
  "crescendo_attack",
131
188
  "deep_inception_attack",
189
+ "deepwordbug_evasion",
190
+ "distillation_extraction",
132
191
  "drattack",
133
192
  "echo_chamber_attack",
193
+ "entropy_membership",
194
+ "equation_solving_extraction",
195
+ "extract_response_text",
196
+ "extract_tool_calls",
134
197
  "genetic_persona_attack",
135
198
  "goat_attack",
136
199
  "goat_v2_attack",
137
200
  "gptfuzzer_attack",
138
201
  "hopskipjump_attack",
202
+ "hopskipjump_evasion",
139
203
  "humor_bypass_attack",
140
204
  "j2_meta_attack",
205
+ "jacobian_extraction",
141
206
  "jbdistill_attack",
142
207
  "jbfuzz_attack",
208
+ "knockoff_extraction",
209
+ "label_only_membership",
210
+ "lira_membership",
211
+ "loss_membership",
143
212
  "lrm_autonomous_attack",
144
213
  "mapf_attack",
145
214
  "multimodal_attack",
146
215
  "nes_attack",
216
+ "nes_inversion",
147
217
  "nexus_attack",
148
218
  "nova_sonic_target",
149
219
  "pair_attack",
150
220
  "persona_hijack_attack",
151
221
  "prompt_attack",
222
+ "pwws_evasion",
152
223
  "quantization_safety_attack",
153
224
  "rainbow_attack",
154
225
  "refusal_aware_attack",
@@ -156,12 +227,20 @@ __all__ = [
156
227
  "reward_hacking_attack",
157
228
  "salami_slicing_attack",
158
229
  "self_persuasion_attack",
230
+ "shadow_model_membership",
159
231
  "simba_attack",
232
+ "simba_evasion",
160
233
  "siren_attack",
234
+ "square_evasion",
161
235
  "tap_attack",
162
236
  "templatefuzz_attack",
237
+ "text_evasion",
238
+ "textbugger_evasion",
239
+ "textfooler_evasion",
240
+ "threshold_membership",
163
241
  "tmap_trajectory_attack",
164
242
  "trojail_attack",
165
243
  "watermark_removal_attack",
166
244
  "zoo_attack",
245
+ "zoo_evasion",
167
246
  ]
@@ -0,0 +1,213 @@
1
+ """Shared base class for the black-box traditional-ML attacks.
2
+
3
+ Extraction, membership inference, and evasion all probe a black-box predict API
4
+ through the same :class:`PredictionTargetSpec` contract, count their queries,
5
+ capture a sample of the (input -> prediction) pairs they send, emit a top-level
6
+ ``study`` span, and enforce a query budget. This module factors that shared
7
+ plumbing into :class:`BlackBoxAttack` so each family only implements its own
8
+ algorithm and its own result-to-span mapping.
9
+
10
+ The base also provides ``_trace_step`` - a capped per-iteration span that records
11
+ the intermediate adversarial state (distance, best score, candidate label /
12
+ confidence, queries so far). Because we own the algorithm loop, every step of the
13
+ attack trajectory is visible in the platform's Traces tab, which is exactly what
14
+ off-the-shelf frameworks (ART, TextAttack) make hard to surface.
15
+ """
16
+
17
+ import typing as t
18
+ from contextlib import nullcontext, suppress
19
+
20
+ import numpy as np
21
+
22
+ from dreadnode.airt.targets.prediction import (
23
+ Prediction,
24
+ PredictionTargetSpec,
25
+ QueryInput,
26
+ predict_many,
27
+ )
28
+
29
+
30
+ @t.runtime_checkable
31
+ class AttackResult(t.Protocol):
32
+ """The common surface every attack result exposes so :meth:`BlackBoxAttack.run`
33
+ can emit spans generically."""
34
+
35
+ query_samples: list[dict[str, t.Any]]
36
+
37
+ @property
38
+ def best_score(self) -> float: ...
39
+
40
+ @property
41
+ def metrics_detail(self) -> dict[str, t.Any]: ...
42
+
43
+
44
+ def sample_input_preview(x: t.Any, n: int = 60) -> str:
45
+ """A compact, display-safe preview of a queried input (text snippet or a few
46
+ numeric features) for the finding's query sample table."""
47
+ if isinstance(x, str):
48
+ return x if len(x) <= n else x[:n] + "..."
49
+ try:
50
+ arr = np.asarray(x, dtype=np.float64).ravel()
51
+ except Exception:
52
+ return str(x)[:n]
53
+ head = ", ".join(f"{v:.3g}" for v in arr[:6])
54
+ return f"[{head}{', ...' if arr.size > 6 else ''}] ({arr.size}d)"
55
+
56
+
57
+ class BlackBoxAttack:
58
+ """Base for a configured black-box attack against a predict API.
59
+
60
+ Subclasses set :attr:`attack_domain` (`model_extraction` /
61
+ `membership_inference` / `adversarial_ml`), a default goal, and implement
62
+ :meth:`_attack_name`, :meth:`_execute`, and :meth:`_span_attributes`. The
63
+ query counter, query-sample capture, phase/step tracing, and the top-level
64
+ ``study`` span are shared here.
65
+ """
66
+
67
+ #: One of "model_extraction", "membership_inference", "adversarial_ml".
68
+ attack_domain: str = ""
69
+ default_goal: str = ""
70
+ default_goal_category: str = ""
71
+
72
+ def __init__(
73
+ self,
74
+ *,
75
+ target: PredictionTargetSpec,
76
+ modality: str = "tabular",
77
+ max_queries: int = 500,
78
+ max_iterations: int = 30,
79
+ seed: int | None = None,
80
+ airt_assessment_id: str | None = None,
81
+ airt_target_model: str | None = None,
82
+ airt_goal: str | None = None,
83
+ airt_goal_category: str | None = None,
84
+ ) -> None:
85
+ self.target = target
86
+ self.modality = modality
87
+ self.max_queries = max_queries
88
+ self.max_iterations = max_iterations
89
+ self.rng = np.random.default_rng(seed)
90
+ self.airt_assessment_id = airt_assessment_id
91
+ self.airt_target_model = airt_target_model or target.name
92
+ self.airt_goal = airt_goal or self.default_goal
93
+ self.airt_goal_category = airt_goal_category or self.default_goal_category
94
+ self._query_count = 0
95
+ #: A sample of real (input -> prediction) pairs so the finding can show
96
+ #: the actual queries the attacker sent, not just the total count.
97
+ self._query_samples: list[dict[str, t.Any]] = []
98
+
99
+ # -- target I/O -------------------------------------------------------- #
100
+ async def _query(self, xs: t.Sequence[QueryInput]) -> list[Prediction]:
101
+ """Query the target, count the queries, and capture a sample."""
102
+ preds = await predict_many(self.target, xs)
103
+ self._query_count += len(xs)
104
+ self._capture_samples(xs, preds)
105
+ return preds
106
+
107
+ def _capture_samples(
108
+ self, xs: t.Sequence[QueryInput], preds: t.Sequence[Prediction], limit: int = 12
109
+ ) -> None:
110
+ for x, p in zip(xs, preds, strict=False):
111
+ if len(self._query_samples) >= limit:
112
+ return
113
+ vec = p.vector
114
+ conf = float(max(vec)) if vec is not None and len(vec) else None
115
+ self._query_samples.append(
116
+ {
117
+ "input": sample_input_preview(x),
118
+ "label": p.hard_label,
119
+ "confidence": round(conf, 4) if conf is not None else None,
120
+ }
121
+ )
122
+
123
+ # -- budget ------------------------------------------------------------ #
124
+ def _budget_left(self) -> int:
125
+ return max(0, self.max_queries - self._query_count)
126
+
127
+ def _over_budget(self) -> bool:
128
+ return self._query_count >= self.max_queries
129
+
130
+ # -- tracing ----------------------------------------------------------- #
131
+ def _phase(self, name: str, **attrs: t.Any) -> t.Any:
132
+ """A coarse task-span phase (e.g. 'perturb + probe target')."""
133
+ try:
134
+ import dreadnode as dn
135
+
136
+ return dn.task_span(name, type="task", attributes={str(k): v for k, v in attrs.items()})
137
+ except Exception:
138
+ return nullcontext()
139
+
140
+ def _trace_step(
141
+ self,
142
+ iteration: int,
143
+ *,
144
+ input: t.Any = None,
145
+ output: t.Any = None,
146
+ metrics: dict[str, float] | None = None,
147
+ **attrs: t.Any,
148
+ ) -> None:
149
+ """Emit a point-in-time span for one algorithm iteration, recording the
150
+ intermediate adversarial state so the full attack trajectory is
151
+ inspectable in the Traces tab.
152
+
153
+ ``input`` is the current candidate (perturbed text / feature vector /
154
+ image preview) the attacker sent; ``output`` is the target's response at
155
+ this step (predicted label + confidence); ``metrics`` are the scalar
156
+ signals (distance, confidence, fidelity) plotted over the run. Capped
157
+ (first 20 iterations, then every 10th) so a long run does not explode the
158
+ trace tree."""
159
+ if iteration >= 20 and iteration % 10 != 0:
160
+ return
161
+ with self._phase(f"step {iteration}", iteration=iteration, **attrs) as span:
162
+ if span is None or not hasattr(span, "log_input"):
163
+ return
164
+ with suppress(Exception):
165
+ if input is not None:
166
+ span.log_input("candidate", input)
167
+ if output is not None:
168
+ span.log_output("prediction", output)
169
+ for key, value in (metrics or {}).items():
170
+ span.log_metric(key, float(value), step=iteration)
171
+
172
+ # -- run scaffold ------------------------------------------------------ #
173
+ @property
174
+ def _attack_name(self) -> str:
175
+ raise NotImplementedError
176
+
177
+ def _study_kwargs(self) -> dict[str, t.Any]:
178
+ """Extra ``study_span`` kwargs beyond the common set (e.g. distance norm)."""
179
+ return {}
180
+
181
+ def _span_attributes(self, result: t.Any) -> dict[str, t.Any]:
182
+ """Map the result onto the ``AIRT_ATTRIBUTE_*`` span attributes to set.
183
+ ``None`` values are skipped."""
184
+ raise NotImplementedError
185
+
186
+ async def _execute(self) -> t.Any:
187
+ raise NotImplementedError
188
+
189
+ async def run(self) -> t.Any:
190
+ import json
191
+
192
+ from dreadnode.tracing.constants import AIRT_ATTRIBUTE_METRICS_DETAIL
193
+ from dreadnode.tracing.spans import study_span
194
+
195
+ with study_span(
196
+ name=self._attack_name,
197
+ airt_assessment_id=self.airt_assessment_id,
198
+ airt_attack_name=self._attack_name,
199
+ airt_attack_domain=self.attack_domain,
200
+ airt_target_model=self.airt_target_model,
201
+ airt_input_modality=self.modality,
202
+ airt_goal=self.airt_goal,
203
+ airt_goal_category=self.airt_goal_category,
204
+ **self._study_kwargs(),
205
+ ) as span:
206
+ result = await self._execute()
207
+ if hasattr(result, "query_samples"):
208
+ result.query_samples = self._query_samples
209
+ for key, value in self._span_attributes(result).items():
210
+ if value is not None:
211
+ span.set_attribute(key, value)
212
+ span.set_attribute(AIRT_ATTRIBUTE_METRICS_DETAIL, json.dumps(result.metrics_detail))
213
+ return result
@@ -0,0 +1,183 @@
1
+ """Optional ART (Adversarial Robustness Toolbox) engine for the traditional-ML
2
+ privacy attacks.
3
+
4
+ When ``adversarial-robustness-toolbox`` is installed (the ``airt-ml`` extra), the
5
+ extraction and membership attacks route their core step through ART's reference
6
+ implementations - CopycatCNN / KnockoffNets for extraction, the black-box
7
+ membership inference attacks for membership - instead of the native
8
+ numpy/sklearn engine. Everything here is import-guarded: if ART (or torch) is
9
+ missing, :func:`art_available` returns ``False`` and callers fall back to the
10
+ native engine, so the base SDK never hard-depends on ART.
11
+
12
+ The victim is always wrapped as a black-box: ART only ever sees a
13
+ ``predict_fn`` backed by predictions we already collected from the target's API,
14
+ so no extra queries are issued and the attack stays honestly black-box.
15
+ """
16
+
17
+ import typing as t
18
+
19
+ import numpy as np
20
+ from loguru import logger
21
+
22
+
23
+ def art_available() -> bool:
24
+ """True when the Adversarial Robustness Toolbox and torch import cleanly.
25
+
26
+ We check for ``art.attacks.extraction`` specifically, not just ``import art``:
27
+ the top-level ``art`` name is also owned by the ASCII-art package the SDK
28
+ depends on, so a bare ``import art`` would false-positive on that library.
29
+ ART is not a hard dependency (it collides with the ASCII-art ``art``); this
30
+ returns True only in an environment where the adversarial toolbox is actually
31
+ installed, otherwise the native engine runs.
32
+ """
33
+ try:
34
+ import torch # noqa: F401
35
+ from art.attacks.extraction import CopycatCNN # noqa: F401
36
+ from art.estimators.classification import BlackBoxClassifier # noqa: F401
37
+ except Exception:
38
+ return False
39
+ return True
40
+
41
+
42
+ def _cached_victim(
43
+ x: np.ndarray,
44
+ proba: np.ndarray,
45
+ nb_classes: int,
46
+ ) -> t.Any:
47
+ """A BlackBoxClassifier whose predict_fn replays already-collected target
48
+ probabilities, keyed by feature-row bytes - ART "queries" it without issuing
49
+ a single extra network call."""
50
+ from art.estimators.classification import BlackBoxClassifier
51
+
52
+ lookup = {row.tobytes(): proba[i] for i, row in enumerate(np.ascontiguousarray(x))}
53
+ uniform = np.full(nb_classes, 1.0 / nb_classes)
54
+
55
+ def predict_fn(batch: np.ndarray) -> np.ndarray:
56
+ rows = np.ascontiguousarray(batch, dtype=x.dtype)
57
+ return np.asarray([lookup.get(r.tobytes(), uniform) for r in rows])
58
+
59
+ return BlackBoxClassifier(
60
+ predict_fn=predict_fn,
61
+ input_shape=(x.shape[1],),
62
+ nb_classes=nb_classes,
63
+ )
64
+
65
+
66
+ def _torch_thieved(n_features: int, nb_classes: int) -> t.Any:
67
+ """A small torch MLP wrapped as an ART PyTorchClassifier - the surrogate that
68
+ ART trains to replicate the victim."""
69
+ import torch
70
+ from art.estimators.classification import PyTorchClassifier
71
+ from torch import nn
72
+
73
+ torch.manual_seed(0)
74
+ model = nn.Sequential(
75
+ nn.Linear(n_features, 128),
76
+ nn.ReLU(),
77
+ nn.Linear(128, 64),
78
+ nn.ReLU(),
79
+ nn.Linear(64, nb_classes),
80
+ )
81
+ return PyTorchClassifier(
82
+ model=model,
83
+ loss=nn.CrossEntropyLoss(),
84
+ optimizer=torch.optim.Adam(model.parameters(), lr=1e-3),
85
+ input_shape=(n_features,),
86
+ nb_classes=nb_classes,
87
+ clip_values=(-1e9, 1e9),
88
+ device_type="cpu",
89
+ )
90
+
91
+
92
+ def art_extract_surrogate(
93
+ strategy: str,
94
+ x: np.ndarray,
95
+ proba: np.ndarray,
96
+ nb_classes: int,
97
+ *,
98
+ nb_epochs: int = 30,
99
+ ) -> t.Any | None:
100
+ """Train a thieved classifier with ART's CopycatCNN (copycat) or KnockoffNets
101
+ (knockoff) against a cached black-box victim.
102
+
103
+ Returns the trained ART classifier (its ``.predict`` yields probabilities), or
104
+ ``None`` if ART is unavailable or the run fails - the caller then falls back to
105
+ the native surrogate. Only ``copycat`` and ``knockoff`` map onto ART; the other
106
+ strategies stay native.
107
+ """
108
+ if strategy not in ("copycat", "knockoff") or not art_available():
109
+ return None
110
+ try:
111
+ from art.attacks.extraction import CopycatCNN, KnockoffNets
112
+
113
+ x = np.ascontiguousarray(x, dtype=np.float32)
114
+ victim = _cached_victim(x, proba, nb_classes)
115
+ thieved = _torch_thieved(x.shape[1], nb_classes)
116
+ n = len(x)
117
+ if strategy == "copycat":
118
+ attack: t.Any = CopycatCNN(
119
+ classifier=victim,
120
+ batch_size_fit=32,
121
+ batch_size_query=32,
122
+ nb_epochs=nb_epochs,
123
+ nb_stolen=n,
124
+ use_probability=False,
125
+ )
126
+ else: # knockoff - soft-label transfer set
127
+ attack = KnockoffNets(
128
+ classifier=victim,
129
+ batch_size_fit=32,
130
+ batch_size_query=32,
131
+ nb_epochs=nb_epochs,
132
+ nb_stolen=n,
133
+ sampling_strategy="random",
134
+ reward="all",
135
+ verbose=False,
136
+ use_probability=True,
137
+ )
138
+ stolen = attack.extract(x=x, thieved_classifier=thieved)
139
+ except Exception as e: # pragma: no cover - defensive fallback
140
+ logger.warning("ART extraction ({}) failed, falling back to native: {}", strategy, e)
141
+ return None
142
+ else:
143
+ logger.debug("ART {} extraction trained thieved classifier on {} samples", strategy, n)
144
+ return stolen
145
+
146
+
147
+ def art_membership_scores(
148
+ method: str,
149
+ members_x: np.ndarray,
150
+ nonmembers_x: np.ndarray,
151
+ member_proba: np.ndarray,
152
+ nonmember_proba: np.ndarray,
153
+ member_labels: np.ndarray,
154
+ nonmember_labels: np.ndarray,
155
+ nb_classes: int,
156
+ ) -> np.ndarray | None:
157
+ """Per-record membership scores via ART's black-box rule-based membership
158
+ inference (Yeom et al.). Returns an array aligned to
159
+ ``[members..., nonmembers...]`` in ``[0, 1]``, or ``None`` to fall back to
160
+ native. Only the ``threshold`` method maps onto ART's black-box rule-based
161
+ attack; ``label_only`` stays native.
162
+ """
163
+ if method != "threshold" or not art_available():
164
+ return None
165
+ try:
166
+ from art.attacks.inference.membership_inference import (
167
+ MembershipInferenceBlackBoxRuleBased,
168
+ )
169
+
170
+ x = np.ascontiguousarray(np.vstack([members_x, nonmembers_x]), dtype=np.float32)
171
+ proba = np.vstack([member_proba, nonmember_proba])
172
+ labels = np.concatenate([member_labels, nonmember_labels]).astype(int)
173
+ victim = _cached_victim(x, proba, nb_classes)
174
+ attack = MembershipInferenceBlackBoxRuleBased(classifier=victim)
175
+ scores = np.asarray(attack.infer(x, labels, probabilities=True), dtype=np.float64)
176
+ # infer(probabilities=True) returns (N, 2) = [P(non-member), P(member)];
177
+ # the member column is the per-record membership score.
178
+ if scores.ndim == 2 and scores.shape[1] == 2:
179
+ scores = scores[:, 1]
180
+ return scores.ravel()
181
+ except Exception as e: # pragma: no cover - defensive fallback
182
+ logger.warning("ART membership (threshold) failed, falling back to native: {}", e)
183
+ return None