dreadnode 2.0.22__tar.gz → 2.0.24__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 (624) hide show
  1. {dreadnode-2.0.22 → dreadnode-2.0.24}/PKG-INFO +2 -1
  2. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/assessment.py +45 -5
  3. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/api/client.py +21 -0
  4. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/airt.py +130 -11
  5. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/main.py +9 -1
  6. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/client/runtime_client.py +36 -0
  7. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/main.py +7 -2
  8. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/app.py +179 -9
  9. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/app.py +177 -3
  10. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/command_dispatcher.py +3 -0
  11. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/commands.py +1 -0
  12. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/dreadnode.tcss +3 -0
  13. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/composer.py +2 -0
  14. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/help_panel.py +5 -2
  15. dreadnode-2.0.24/dreadnode/app/tui/widgets/rewind_picker.py +203 -0
  16. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/tool_progress.py +1 -1
  17. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/dependencies-and-checks.md +19 -7
  18. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/sdk/capabilities.md +38 -0
  19. dreadnode-2.0.24/dreadnode/capabilities/install.py +226 -0
  20. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/capabilities/loader.py +46 -0
  21. {dreadnode-2.0.22 → dreadnode-2.0.24}/pyproject.toml +2 -1
  22. {dreadnode-2.0.22 → dreadnode-2.0.24}/.gitignore +0 -0
  23. {dreadnode-2.0.22 → dreadnode-2.0.24}/LICENSE +0 -0
  24. {dreadnode-2.0.22 → dreadnode-2.0.24}/README.md +0 -0
  25. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/__init__.py +0 -0
  26. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/__main__.py +0 -0
  27. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/__init__.py +0 -0
  28. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/agent.py +0 -0
  29. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/events.py +0 -0
  30. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/exceptions.py +0 -0
  31. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/format.py +0 -0
  32. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/hooks.py +0 -0
  33. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/judge.py +0 -0
  34. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/mcp/__init__.py +0 -0
  35. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/mcp/auth.py +0 -0
  36. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/mcp/client.py +0 -0
  37. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/mcp/config.py +0 -0
  38. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/mcp/server.py +0 -0
  39. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/process_judge.py +0 -0
  40. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/reactions.py +0 -0
  41. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/skills.py +0 -0
  42. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/stopping.py +0 -0
  43. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/subagent.py +0 -0
  44. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/tool_resolution.py +0 -0
  45. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/tools.py +0 -0
  46. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/trajectory.py +0 -0
  47. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/__init__.py +0 -0
  48. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/adversarial_reasoning.py +0 -0
  49. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/advpromptier.py +0 -0
  50. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/alignment_faking.py +0 -0
  51. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/analogy_escalation.py +0 -0
  52. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/analytics/__init__.py +0 -0
  53. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/analytics/aggregator.py +0 -0
  54. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/analytics/classifier.py +0 -0
  55. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/analytics/compliance.py +0 -0
  56. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/analytics/engine.py +0 -0
  57. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/analytics/recommendations.py +0 -0
  58. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/analytics/types.py +0 -0
  59. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/aprt_progressive.py +0 -0
  60. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/attention_shifting.py +0 -0
  61. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/autodan_turbo.py +0 -0
  62. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/autoredteamer.py +0 -0
  63. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/beast.py +0 -0
  64. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/compliance/__init__.py +0 -0
  65. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/compliance/atlas.py +0 -0
  66. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/compliance/nist.py +0 -0
  67. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/compliance/owasp.py +0 -0
  68. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/compliance/owasp_agentic.py +0 -0
  69. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/compliance/saif.py +0 -0
  70. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/constants.py +0 -0
  71. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/cot_jailbreak.py +0 -0
  72. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/crescendo.py +0 -0
  73. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/__init__.py +0 -0
  74. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/assets/audio/adversarial_query.mp3 +0 -0
  75. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/assets/image/bomb.jpg +0 -0
  76. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/assets/image/meth.png +0 -0
  77. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/prompts/adversarial_benchmark_subset.csv +0 -0
  78. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/prompts/ai_safety.csv +0 -0
  79. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/rubrics/data_exfiltration.yaml +0 -0
  80. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/rubrics/goal_hijacking.yaml +0 -0
  81. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/rubrics/memory_poisoning.yaml +0 -0
  82. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/rubrics/privilege_escalation.yaml +0 -0
  83. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/rubrics/rce.yaml +0 -0
  84. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/rubrics/scope_creep.yaml +0 -0
  85. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/rubrics/tool_chaining.yaml +0 -0
  86. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/rubrics/tool_selection_safety.yaml +0 -0
  87. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/rubrics/unbounded_agency.yaml +0 -0
  88. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/rubrics/web_chatbot_security.yaml +0 -0
  89. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/templates/crescendo/variant_1.yaml +0 -0
  90. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/templates/crescendo/variant_2.yaml +0 -0
  91. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/templates/crescendo/variant_3.yaml +0 -0
  92. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/templates/crescendo/variant_4.yaml +0 -0
  93. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/templates/crescendo/variant_5.yaml +0 -0
  94. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/deep_inception.py +0 -0
  95. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/drattack.py +0 -0
  96. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/echo_chamber.py +0 -0
  97. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/events.py +0 -0
  98. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/genetic_persona.py +0 -0
  99. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/goat.py +0 -0
  100. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/goat_v2.py +0 -0
  101. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/gptfuzzer.py +0 -0
  102. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/humor_bypass.py +0 -0
  103. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/image.py +0 -0
  104. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/j2_meta.py +0 -0
  105. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/jbdistill.py +0 -0
  106. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/jbfuzz.py +0 -0
  107. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/lrm_autonomous.py +0 -0
  108. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/mapf.py +0 -0
  109. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/multimodal.py +0 -0
  110. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/nexus.py +0 -0
  111. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/pair.py +0 -0
  112. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/persona_hijack.py +0 -0
  113. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/prompt.py +0 -0
  114. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/quantization_safety.py +0 -0
  115. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/rainbow.py +0 -0
  116. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/refusal_aware.py +0 -0
  117. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/renellm.py +0 -0
  118. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/reporting/__init__.py +0 -0
  119. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/reporting/json_report.py +0 -0
  120. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/reporting/llm_summary.py +0 -0
  121. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/reporting/markdown.py +0 -0
  122. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/reward_hacking.py +0 -0
  123. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/salami_slicing.py +0 -0
  124. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/self_persuasion.py +0 -0
  125. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/siren.py +0 -0
  126. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/tap.py +0 -0
  127. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/templatefuzz.py +0 -0
  128. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/tmap_trajectory.py +0 -0
  129. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/trojail.py +0 -0
  130. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/watermark_removal.py +0 -0
  131. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/__init__.py +0 -0
  132. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/api/__init__.py +0 -0
  133. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/api/models.py +0 -0
  134. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/__init__.py +0 -0
  135. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/args.py +0 -0
  136. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/capability.py +0 -0
  137. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/dataset.py +0 -0
  138. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/environment.py +0 -0
  139. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/evaluation.py +0 -0
  140. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/inference_model.py +0 -0
  141. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/model.py +0 -0
  142. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/optimize.py +0 -0
  143. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/runtime.py +0 -0
  144. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/sandbox.py +0 -0
  145. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/secret.py +0 -0
  146. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/session.py +0 -0
  147. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/shared.py +0 -0
  148. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/task.py +0 -0
  149. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/templates/__init__.py +0 -0
  150. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/templates/init/__init__.py +0 -0
  151. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/templates/init/challenge/Dockerfile +0 -0
  152. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/templates/init/docker-compose.yaml +0 -0
  153. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/templates/init/provision.sh +0 -0
  154. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/templates/init/solution.sh +0 -0
  155. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/templates/init/task-remote.yaml.tmpl +0 -0
  156. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/templates/init/task.yaml.tmpl +0 -0
  157. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/templates/init/teardown.sh +0 -0
  158. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/templates/init/verify.sh +0 -0
  159. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/train.py +0 -0
  160. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/worlds.py +0 -0
  161. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/client/__init__.py +0 -0
  162. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/client/interactive.py +0 -0
  163. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/client/managed_client.py +0 -0
  164. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/client/models.py +0 -0
  165. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/client/transports.py +0 -0
  166. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/config.py +0 -0
  167. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/env.py +0 -0
  168. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/model_catalog.py +0 -0
  169. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/paths.py +0 -0
  170. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/print_mode.py +0 -0
  171. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/__init__.py +0 -0
  172. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/auth.py +0 -0
  173. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/capability_manager.py +0 -0
  174. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/model_resolution.py +0 -0
  175. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/prompt.py +0 -0
  176. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/prompt_registry.py +0 -0
  177. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/runtime_events.py +0 -0
  178. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/session_hydrator.py +0 -0
  179. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/session_persistence.py +0 -0
  180. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/turn_coordinator.py +0 -0
  181. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/utils.py +0 -0
  182. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/websocket.py +0 -0
  183. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/worker_manager.py +0 -0
  184. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/__init__.py +0 -0
  185. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/auth_flow.py +0 -0
  186. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/capabilities_manager.py +0 -0
  187. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/connection.py +0 -0
  188. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/error_handler.py +0 -0
  189. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/model_manager.py +0 -0
  190. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/model_variants.py +0 -0
  191. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/profile_manager.py +0 -0
  192. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/runtime_cache.py +0 -0
  193. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screen_router.py +0 -0
  194. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/__init__.py +0 -0
  195. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/auth.py +0 -0
  196. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/base.py +0 -0
  197. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/capabilities.py +0 -0
  198. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/capability_docs.py +0 -0
  199. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/connection_error.py +0 -0
  200. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/console.py +0 -0
  201. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/environments.py +0 -0
  202. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/evaluations.py +0 -0
  203. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/model_picker.py +0 -0
  204. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/models.py +0 -0
  205. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/raw_spans.py +0 -0
  206. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/runtimes.py +0 -0
  207. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/sandboxes.py +0 -0
  208. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/secrets.py +0 -0
  209. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/services.py +0 -0
  210. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/sessions.py +0 -0
  211. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/theme_showcase.py +0 -0
  212. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/traces.py +0 -0
  213. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/workspaces.py +0 -0
  214. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/sessions_manager.py +0 -0
  215. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/spans_reader.py +0 -0
  216. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/status_messages.py +0 -0
  217. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/theme.py +0 -0
  218. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/tool_format.py +0 -0
  219. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/turn_coordinator.py +0 -0
  220. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/turn_lifecycle.py +0 -0
  221. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/turn_reducer.py +0 -0
  222. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/turn_state_phase.py +0 -0
  223. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/update_check.py +0 -0
  224. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/__init__.py +0 -0
  225. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/agent_dialog.py +0 -0
  226. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/agent_suggester.py +0 -0
  227. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/confirm_modal.py +0 -0
  228. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/context_bar.py +0 -0
  229. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/conversation.py +0 -0
  230. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/flash.py +0 -0
  231. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/header_bar.py +0 -0
  232. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/human_prompt.py +0 -0
  233. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/mention_overlay.py +0 -0
  234. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/message_queue.py +0 -0
  235. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/new_messages_pill.py +0 -0
  236. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/overlay_mixin.py +0 -0
  237. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/permission_prompt.py +0 -0
  238. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/profile_dialog.py +0 -0
  239. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/prompt_info.py +0 -0
  240. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/session_sidebar.py +0 -0
  241. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/skills_dialog.py +0 -0
  242. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/slash_overlay.py +0 -0
  243. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/status_bar.py +0 -0
  244. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/throbber.py +0 -0
  245. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/tool.py +0 -0
  246. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/tools_dialog.py +0 -0
  247. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/welcome.py +0 -0
  248. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/whoami.py +0 -0
  249. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/wire_events.py +0 -0
  250. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/__init__.py +0 -0
  251. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/MAINTAINING.md +0 -0
  252. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/agents/dreadnode.md +0 -0
  253. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/capability.yaml +0 -0
  254. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/SKILL.md +0 -0
  255. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/capability-improvement.md +0 -0
  256. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/promoting-capabilities.md +0 -0
  257. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/INDEX.md +0 -0
  258. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/agents.md +0 -0
  259. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/env-vars.md +0 -0
  260. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/events.md +0 -0
  261. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/flags.md +0 -0
  262. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/hooks.md +0 -0
  263. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/installing.md +0 -0
  264. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/manifest.md +0 -0
  265. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/mcp-servers.md +0 -0
  266. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/overview.md +0 -0
  267. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/policies.md +0 -0
  268. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/publishing.md +0 -0
  269. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/quickstart.md +0 -0
  270. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/skills.md +0 -0
  271. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/tools.md +0 -0
  272. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/workers-reference.md +0 -0
  273. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/workers.md +0 -0
  274. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/writing-skills.md +0 -0
  275. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/guides/capability-optimization-loop.md +0 -0
  276. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/sdk/agents.md +0 -0
  277. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/tui/default-tools.md +0 -0
  278. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/runtime-default-capability.md +0 -0
  279. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/SKILL.md +0 -0
  280. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/INDEX.md +0 -0
  281. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/airt.md +0 -0
  282. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/capability.md +0 -0
  283. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/dataset.md +0 -0
  284. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/env.md +0 -0
  285. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/evaluation.md +0 -0
  286. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/inference-model.md +0 -0
  287. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/main.md +0 -0
  288. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/model.md +0 -0
  289. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/optimize.md +0 -0
  290. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/overview.md +0 -0
  291. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/runtime.md +0 -0
  292. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/sandbox.md +0 -0
  293. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/secret.md +0 -0
  294. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/task.md +0 -0
  295. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/train.md +0 -0
  296. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/worlds.md +0 -0
  297. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/getting-started/authentication.md +0 -0
  298. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/SKILL.md +0 -0
  299. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/INDEX.md +0 -0
  300. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/capabilities/installing.md +0 -0
  301. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/capabilities/overview.md +0 -0
  302. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/getting-started/authentication.md +0 -0
  303. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/getting-started/overview.md +0 -0
  304. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/getting-started/quickstart.md +0 -0
  305. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/chat-models.md +0 -0
  306. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/credits.md +0 -0
  307. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/organizations.md +0 -0
  308. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/overview.md +0 -0
  309. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/projects.md +0 -0
  310. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/secrets.md +0 -0
  311. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/settings.md +0 -0
  312. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/users.md +0 -0
  313. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/workspaces.md +0 -0
  314. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/configuration.md +0 -0
  315. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/managing.md +0 -0
  316. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/manifest-reference.md +0 -0
  317. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/overview.md +0 -0
  318. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/quickstart.md +0 -0
  319. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/serve.md +0 -0
  320. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/sandboxes/environment-lifecycle.md +0 -0
  321. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/sandboxes/inspecting.md +0 -0
  322. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/sandboxes/overview.md +0 -0
  323. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/getting-started/SKILL.md +0 -0
  324. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/research-capabilities/SKILL.md +0 -0
  325. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/self-improvement/.gitignore +0 -0
  326. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/self-improvement/capability.yaml +0 -0
  327. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/self-improvement/hooks/__init__.py +0 -0
  328. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/self-improvement/hooks/observer.py +0 -0
  329. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/__init__.py +0 -0
  330. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/classifier.py +0 -0
  331. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/reflector_goal.py +0 -0
  332. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/skill_io.py +0 -0
  333. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/self-improvement/skills-promoted/.gitkeep +0 -0
  334. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/self-improvement/skills-proposed/.gitkeep +0 -0
  335. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/self-improvement/tools/__init__.py +0 -0
  336. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/self-improvement/tools/reflector.py +0 -0
  337. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/self-improvement/tools/skill_stats.py +0 -0
  338. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/capabilities/__init__.py +0 -0
  339. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/capabilities/capability.py +0 -0
  340. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/capabilities/flags.py +0 -0
  341. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/capabilities/sync.py +0 -0
  342. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/capabilities/tool_rules.py +0 -0
  343. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/capabilities/types.py +0 -0
  344. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/capabilities/worker.py +0 -0
  345. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/capabilities/worker_runner.py +0 -0
  346. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/__init__.py +0 -0
  347. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/conditions.py +0 -0
  348. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/discovery.py +0 -0
  349. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/environment.py +0 -0
  350. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/exceptions.py +0 -0
  351. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/execution.py +0 -0
  352. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/hook.py +0 -0
  353. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/judge.py +0 -0
  354. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/load.py +0 -0
  355. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/log.py +0 -0
  356. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/meta/__init__.py +0 -0
  357. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/meta/config.py +0 -0
  358. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/meta/context.py +0 -0
  359. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/meta/hydrate.py +0 -0
  360. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/meta/introspect.py +0 -0
  361. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/metric.py +0 -0
  362. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/object.py +0 -0
  363. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/scorer.py +0 -0
  364. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/serialization.py +0 -0
  365. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/stopping.py +0 -0
  366. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/task.py +0 -0
  367. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/templating.py +0 -0
  368. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/transforms.py +0 -0
  369. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/types/__init__.py +0 -0
  370. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/types/audio.py +0 -0
  371. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/types/base.py +0 -0
  372. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/types/common.py +0 -0
  373. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/types/image.py +0 -0
  374. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/types/object_3d.py +0 -0
  375. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/types/table.py +0 -0
  376. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/types/text.py +0 -0
  377. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/types/video.py +0 -0
  378. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/util.py +0 -0
  379. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/datasets/__init__.py +0 -0
  380. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/datasets/dataset.py +0 -0
  381. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/datasets/hf.py +0 -0
  382. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/datasets/local.py +0 -0
  383. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/evaluations/__init__.py +0 -0
  384. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/evaluations/console.py +0 -0
  385. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/evaluations/evaluation.py +0 -0
  386. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/evaluations/events.py +0 -0
  387. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/evaluations/format.py +0 -0
  388. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/evaluations/result.py +0 -0
  389. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/evaluations/sample.py +0 -0
  390. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/__init__.py +0 -0
  391. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/caching.py +0 -0
  392. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/chat.py +0 -0
  393. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/data.py +0 -0
  394. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/exceptions.py +0 -0
  395. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/generator/__init__.py +0 -0
  396. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/generator/base.py +0 -0
  397. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/generator/http.py +0 -0
  398. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/generator/litellm_.py +0 -0
  399. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/generator/transformers_.py +0 -0
  400. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/generator/vllm_.py +0 -0
  401. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/message.py +0 -0
  402. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/models.py +0 -0
  403. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/parsing.py +0 -0
  404. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/tokenizer/__init__.py +0 -0
  405. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/tokenizer/base.py +0 -0
  406. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/tokenizer/transformers_.py +0 -0
  407. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/utils.py +0 -0
  408. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/models/__init__.py +0 -0
  409. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/models/hf.py +0 -0
  410. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/models/local.py +0 -0
  411. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/models/model.py +0 -0
  412. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/__init__.py +0 -0
  413. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/adapters/__init__.py +0 -0
  414. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/adapters/_env_eval.py +0 -0
  415. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/adapters/agent.py +0 -0
  416. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/adapters/env.py +0 -0
  417. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/adapters/runtime.py +0 -0
  418. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/adapters/stack.py +0 -0
  419. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/api.py +0 -0
  420. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/backends/__init__.py +0 -0
  421. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/backends/base.py +0 -0
  422. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/backends/gepa.py +0 -0
  423. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/collectors.py +0 -0
  424. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/config.py +0 -0
  425. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/console.py +0 -0
  426. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/events.py +0 -0
  427. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/format.py +0 -0
  428. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/jobs.py +0 -0
  429. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/result.py +0 -0
  430. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/sampler.py +0 -0
  431. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/sampling.py +0 -0
  432. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/search.py +0 -0
  433. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/stopping.py +0 -0
  434. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/study.py +0 -0
  435. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/trial.py +0 -0
  436. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/packaging/__init__.py +0 -0
  437. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/packaging/loader.py +0 -0
  438. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/packaging/manifest.py +0 -0
  439. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/packaging/oci.py +0 -0
  440. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/packaging/package.py +0 -0
  441. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/packaging/task_validation.py +0 -0
  442. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/policies/__init__.py +0 -0
  443. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/policies/guard.py +0 -0
  444. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/policies/rubrics/process/default.yaml +0 -0
  445. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/py.typed +0 -0
  446. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/samplers/__init__.py +0 -0
  447. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/samplers/boundary.py +0 -0
  448. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/samplers/fuzzing.py +0 -0
  449. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/samplers/graph.py +0 -0
  450. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/samplers/grid.py +0 -0
  451. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/samplers/image.py +0 -0
  452. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/samplers/mapelites.py +0 -0
  453. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/samplers/optuna.py +0 -0
  454. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/samplers/random.py +0 -0
  455. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/samplers/registry.py +0 -0
  456. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/samplers/strategy.py +0 -0
  457. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/__init__.py +0 -0
  458. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/advanced_jailbreak_detection.py +0 -0
  459. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/agent_security.py +0 -0
  460. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/agentic.py +0 -0
  461. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/agentic_workflow.py +0 -0
  462. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/attack_outcome.py +0 -0
  463. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/classification.py +0 -0
  464. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/consistency.py +0 -0
  465. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/contains.py +0 -0
  466. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/cosine_sim.py +0 -0
  467. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/credentials.py +0 -0
  468. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/crucible.py +0 -0
  469. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/documentation_security.py +0 -0
  470. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/exfiltration_detection.py +0 -0
  471. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/format.py +0 -0
  472. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/harm.py +0 -0
  473. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/ide_security.py +0 -0
  474. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/image.py +0 -0
  475. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/json.py +0 -0
  476. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/judge.py +0 -0
  477. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/judge_ensemble.py +0 -0
  478. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/length.py +0 -0
  479. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/lexical.py +0 -0
  480. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/mcp_security.py +0 -0
  481. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/memorization.py +0 -0
  482. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/multi_agent_security.py +0 -0
  483. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/pii.py +0 -0
  484. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/prompt_leak.py +0 -0
  485. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/readability.py +0 -0
  486. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/reasoning_security.py +0 -0
  487. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/sentiment.py +0 -0
  488. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/similarity.py +0 -0
  489. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/structural_detection.py +0 -0
  490. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/supply_chain_detection.py +0 -0
  491. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/storage/__init__.py +0 -0
  492. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/storage/providers.py +0 -0
  493. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/storage/session_store.py +0 -0
  494. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/storage/storage.py +0 -0
  495. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/__init__.py +0 -0
  496. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/_ripgrep.py +0 -0
  497. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/apply_patch.py +0 -0
  498. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/dreadnode_cli.py +0 -0
  499. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/editing.py +0 -0
  500. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/execute.py +0 -0
  501. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/fetch.py +0 -0
  502. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/glob.py +0 -0
  503. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/grep.py +0 -0
  504. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/interaction.py +0 -0
  505. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/ls.py +0 -0
  506. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/memory.py +0 -0
  507. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/read.py +0 -0
  508. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/report.py +0 -0
  509. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/task.py +0 -0
  510. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/think.py +0 -0
  511. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/todo.py +0 -0
  512. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/trajectory_search.py +0 -0
  513. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/web_extract.py +0 -0
  514. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/web_search.py +0 -0
  515. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/write.py +0 -0
  516. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tracing/__init__.py +0 -0
  517. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tracing/constants.py +0 -0
  518. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tracing/convert.py +0 -0
  519. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tracing/exporter.py +0 -0
  520. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tracing/exporters.py +0 -0
  521. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tracing/span.py +0 -0
  522. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tracing/spans.py +0 -0
  523. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tracing/trace_converter.py +0 -0
  524. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/__init__.py +0 -0
  525. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/_progress.py +0 -0
  526. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/base.py +0 -0
  527. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/dpo.py +0 -0
  528. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/env_rollouts.py +0 -0
  529. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/etl/__init__.py +0 -0
  530. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/etl/_common.py +0 -0
  531. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/etl/rl.py +0 -0
  532. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/etl/sft.py +0 -0
  533. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/etl/worlds.py +0 -0
  534. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/events.py +0 -0
  535. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/grpo.py +0 -0
  536. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/jobs.py +0 -0
  537. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/models.py +0 -0
  538. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ppo.py +0 -0
  539. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/prime.py +0 -0
  540. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/__init__.py +0 -0
  541. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/async_trainer.py +0 -0
  542. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/config.py +0 -0
  543. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/coordinator.py +0 -0
  544. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/distributed.py +0 -0
  545. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/dpo.py +0 -0
  546. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/experience.py +0 -0
  547. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/fsdp2_learner.py +0 -0
  548. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/inference.py +0 -0
  549. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/learner.py +0 -0
  550. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/multi_turn.py +0 -0
  551. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/ppo.py +0 -0
  552. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/reward_model.py +0 -0
  553. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/rollout_env.py +0 -0
  554. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/rollout_worker.py +0 -0
  555. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/sft.py +0 -0
  556. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/trainer.py +0 -0
  557. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/recipes.py +0 -0
  558. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/rewards/__init__.py +0 -0
  559. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/rewards/aggregator.py +0 -0
  560. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/rewards/functions.py +0 -0
  561. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/rewards/scorer_bridge.py +0 -0
  562. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/rewards/shaping.py +0 -0
  563. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/rewards/types.py +0 -0
  564. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/rollouts/__init__.py +0 -0
  565. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/rollouts/adapters.py +0 -0
  566. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/rollouts/agent_rollout.py +0 -0
  567. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/rollouts/orchestrator.py +0 -0
  568. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/rollouts/types.py +0 -0
  569. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/rollouts/worlds.py +0 -0
  570. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/serving/__init__.py +0 -0
  571. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/serving/vllm_client.py +0 -0
  572. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/sft.py +0 -0
  573. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/tinker/__init__.py +0 -0
  574. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/tinker/config.py +0 -0
  575. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/tinker/data.py +0 -0
  576. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/tinker/renderer.py +0 -0
  577. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/tinker/rl.py +0 -0
  578. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/tinker/trainer.py +0 -0
  579. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/tinker_sft.py +0 -0
  580. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/utils.py +0 -0
  581. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/__init__.py +0 -0
  582. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/advanced_jailbreak.py +0 -0
  583. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/adversarial_suffix.py +0 -0
  584. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/agent_skill.py +0 -0
  585. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/agentic_workflow.py +0 -0
  586. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/audio.py +0 -0
  587. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/backdoor_finetune.py +0 -0
  588. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/browser_agent_attacks.py +0 -0
  589. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/cipher.py +0 -0
  590. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/competitive_parity.py +0 -0
  591. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/constitutional.py +0 -0
  592. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/document.py +0 -0
  593. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/documentation_poison.py +0 -0
  594. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/encoding.py +0 -0
  595. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/exfiltration.py +0 -0
  596. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/flip_attack.py +0 -0
  597. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/guardrail_bypass.py +0 -0
  598. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/ide_injection.py +0 -0
  599. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/image.py +0 -0
  600. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/injection.py +0 -0
  601. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/json_tools.py +0 -0
  602. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/language.py +0 -0
  603. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/logic_bomb.py +0 -0
  604. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/mcp_attacks.py +0 -0
  605. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/multi_agent_attacks.py +0 -0
  606. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/multimodal_attacks.py +0 -0
  607. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/persuasion.py +0 -0
  608. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/perturbation.py +0 -0
  609. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/pii_extraction.py +0 -0
  610. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/pythonic_tools.py +0 -0
  611. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/rag_poisoning.py +0 -0
  612. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/reasoning_attacks.py +0 -0
  613. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/refine.py +0 -0
  614. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/response_steering.py +0 -0
  615. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/structural_exploits.py +0 -0
  616. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/stylistic.py +0 -0
  617. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/substitution.py +0 -0
  618. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/supply_chain.py +0 -0
  619. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/swap.py +0 -0
  620. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/system_prompt_extraction.py +0 -0
  621. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/text.py +0 -0
  622. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/video.py +0 -0
  623. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/xml_tools.py +0 -0
  624. {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dreadnode
3
- Version: 2.0.22
3
+ Version: 2.0.24
4
4
  Summary: Dreadnode SDK
5
5
  Project-URL: Homepage, https://dreadnode.io
6
6
  Project-URL: Documentation, https://docs.dreadnode.io
@@ -27,6 +27,7 @@ Requires-Dist: loguru>=0.7.3
27
27
  Requires-Dist: markdownify<2.0.0,>=1.1.0
28
28
  Requires-Dist: mcp<2.0.0,>=1.25.0
29
29
  Requires-Dist: moviepy<3.0.0,>=2.1.2
30
+ Requires-Dist: networkx>=3.6.1
30
31
  Requires-Dist: numpy<=2.3.5,>=2.3.0
31
32
  Requires-Dist: optuna<5.0.0,>=4.5.0
32
33
  Requires-Dist: orjson>=3.11.5
@@ -23,6 +23,7 @@ import contextlib
23
23
  import contextvars
24
24
  import os
25
25
  import signal
26
+ import threading
26
27
  import typing as t
27
28
  from pathlib import Path
28
29
 
@@ -57,6 +58,26 @@ def _get_platform_context() -> tuple[ApiClient, Profile] | None:
57
58
  return None
58
59
 
59
60
 
61
+ # Thread-local storage for injected platform context
62
+ _thread_local = threading.local()
63
+
64
+
65
+ def _set_platform_context(api: ApiClient, profile: Profile) -> None:
66
+ """Set platform context for the current thread (used by AIRT CLI)."""
67
+ _thread_local.api = api
68
+ _thread_local.profile = profile
69
+
70
+
71
+ def _get_platform_context_with_fallback() -> tuple[ApiClient, Profile] | None:
72
+ """Get platform context with CLI injection fallback."""
73
+ # First try thread-local injected context (from AIRT CLI)
74
+ if hasattr(_thread_local, "api") and hasattr(_thread_local, "profile"):
75
+ return _thread_local.api, _thread_local.profile
76
+
77
+ # Fallback to global DEFAULT_INSTANCE
78
+ return _get_platform_context()
79
+
80
+
60
81
  class Assessment:
61
82
  """Orchestrates multi-attack assessments.
62
83
 
@@ -91,6 +112,7 @@ class Assessment:
91
112
  workflow_run_id: str | None = None,
92
113
  workflow_script: str | None = None,
93
114
  project_id: str | None = None,
115
+ runtime_id: str | None = None,
94
116
  ) -> None:
95
117
  self.name = name
96
118
  self.description = description
@@ -116,6 +138,7 @@ class Assessment:
116
138
  self._workflow_run_id = workflow_run_id
117
139
  self._workflow_script = workflow_script
118
140
  self._project_id = project_id
141
+ self._runtime_id = runtime_id
119
142
 
120
143
  self._session_id = session_id or os.environ.get("DREADNODE_SESSION_ID")
121
144
  if self._session_id is None:
@@ -177,7 +200,7 @@ class Assessment:
177
200
  if self._assessment_id is not None:
178
201
  return self._assessment_id
179
202
 
180
- ctx = _get_platform_context()
203
+ ctx = _get_platform_context_with_fallback()
181
204
  if ctx is None:
182
205
  logger.debug("SDK offline -- assessment not registered with platform")
183
206
  return None
@@ -192,11 +215,28 @@ class Assessment:
192
215
  return None
193
216
 
194
217
  try:
218
+ # Get runtime_id - try to use a default runtime for the project
219
+ runtime_id = getattr(self, "_runtime_id", None)
220
+ if runtime_id is None:
221
+ # Auto-discover a runtime for this project (CLI users shouldn't need to specify this)
222
+ try:
223
+ runtimes_resp = api.list_runtimes(profile.org_key, profile.workspace_key)
224
+ runtime_items = runtimes_resp.get("items", [])
225
+ matching_runtimes = [r for r in runtime_items if r["project_id"] == project_id]
226
+ if matching_runtimes:
227
+ runtime_id = matching_runtimes[0]["id"]
228
+ logger.debug(f"Auto-selected runtime {runtime_id} for project {project_id}")
229
+ else:
230
+ logger.warning(f"No runtimes found for project {project_id}")
231
+ except Exception as e:
232
+ logger.debug(f"Failed to auto-discover runtime for project: {e}")
233
+
195
234
  result = api.create_airt_assessment(
196
235
  profile.org_key,
197
236
  profile.workspace_key,
198
237
  name=self.name,
199
238
  project_id=project_id,
239
+ runtime_id=runtime_id,
200
240
  description=self.description,
201
241
  session_id=self._session_id,
202
242
  target_model=self.target_model,
@@ -402,7 +442,7 @@ class Assessment:
402
442
  await self.register()
403
443
  # Notify the platform that execution has started (sets started_at server-side)
404
444
  if self._assessment_id is not None:
405
- ctx = _get_platform_context()
445
+ ctx = _get_platform_context_with_fallback()
406
446
  if ctx is not None:
407
447
  api, session = ctx
408
448
  try:
@@ -459,7 +499,7 @@ class Assessment:
459
499
  provider.force_flush(timeout_millis=10_000)
460
500
 
461
501
  # Use the sync API client directly — no async gymnastics
462
- ctx = _get_platform_context()
502
+ ctx = _get_platform_context_with_fallback()
463
503
  if ctx is None or self._assessment_id is None:
464
504
  return
465
505
 
@@ -499,7 +539,7 @@ class Assessment:
499
539
  Returns:
500
540
  True if successfully marked, False otherwise.
501
541
  """
502
- ctx = _get_platform_context()
542
+ ctx = _get_platform_context_with_fallback()
503
543
  if ctx is None or self._assessment_id is None:
504
544
  return False
505
545
 
@@ -527,7 +567,7 @@ class Assessment:
527
567
  Returns:
528
568
  True if successfully marked, False otherwise.
529
569
  """
530
- ctx = _get_platform_context()
570
+ ctx = _get_platform_context_with_fallback()
531
571
  if ctx is None or self._assessment_id is None:
532
572
  return False
533
573
 
@@ -2604,6 +2604,27 @@ class ApiClient:
2604
2604
  )
2605
2605
  return t.cast("dict[str, t.Any]", response.json())
2606
2606
 
2607
+ def rewind_transcript(
2608
+ self,
2609
+ org: str,
2610
+ workspace: str,
2611
+ session_id: str,
2612
+ *,
2613
+ from_seq: int,
2614
+ ) -> dict[str, t.Any]:
2615
+ """POST /org/{org}/ws/{workspace}/sessions/{session_id}/rewind.
2616
+
2617
+ Hard-truncates the transcript at ``from_seq`` (target user-message
2618
+ seq). Returns ``RewindTranscriptResponse`` dict with
2619
+ ``deleted_count``, ``target_seq``, and ``restored_content``.
2620
+ """
2621
+ response = self.request(
2622
+ "POST",
2623
+ f"/org/{org}/ws/{workspace}/sessions/{session_id}/rewind",
2624
+ json_data={"from_seq": from_seq},
2625
+ )
2626
+ return t.cast("dict[str, t.Any]", response.json())
2627
+
2607
2628
  # =========================================================================
2608
2629
  # Worlds
2609
2630
  # =========================================================================
@@ -64,6 +64,46 @@ def _parse_json_object_option(value: str | None, *, field_name: str) -> dict[str
64
64
  return parsed
65
65
 
66
66
 
67
+ def _resolve_project_id(api, profile, project):
68
+ """Resolve project name to UUID, creating the project if it doesn't exist."""
69
+ from uuid import UUID
70
+
71
+ candidate = project or getattr(profile, "project_key", None)
72
+ if not candidate:
73
+ return None
74
+
75
+ # Check if already a UUID
76
+ try:
77
+ UUID(str(candidate))
78
+ return str(candidate) # Already a UUID
79
+ except ValueError:
80
+ pass # Not a UUID, need to resolve
81
+
82
+ # Try to resolve project name to UUID
83
+ try:
84
+ resolved = api.get_project(profile.org_key, profile.workspace_key, str(candidate))
85
+ return str(resolved.id)
86
+ except Exception as get_error:
87
+ # Project doesn't exist, try to create it
88
+ try:
89
+ print(f"[PROJECT DEBUG] Project '{candidate}' not found, creating it...")
90
+ created = api.create_project(
91
+ profile.org_key,
92
+ profile.workspace_key,
93
+ name=str(candidate),
94
+ key=str(candidate),
95
+ description="Auto-created project for AIRT CLI run",
96
+ )
97
+ print(
98
+ f"[PROJECT DEBUG] Successfully created project '{candidate}' with ID {created.id}"
99
+ )
100
+ return str(created.id)
101
+ except Exception as create_error:
102
+ print(f"[PROJECT DEBUG] Failed to resolve project '{candidate}': {get_error}")
103
+ print(f"[PROJECT DEBUG] Failed to create project '{candidate}': {create_error}")
104
+ return None
105
+
106
+
67
107
  _SEVERITY_COLORS = {
68
108
  "critical": "red",
69
109
  "high": "red",
@@ -1126,6 +1166,9 @@ def run(
1126
1166
  print_error(str(e))
1127
1167
  return
1128
1168
 
1169
+ # Capture original project argument before connect() clears it
1170
+ original_project = platform.project
1171
+
1129
1172
  # Configure SDK and validate scope to populate project_id
1130
1173
  _api, profile = platform.connect()
1131
1174
 
@@ -1151,18 +1194,49 @@ def run(
1151
1194
  console.print()
1152
1195
 
1153
1196
  async def _run() -> None:
1197
+ # Determine project for SDK configuration
1198
+ # Use original CLI argument, fallback to profile, environment, then 'default'
1199
+ import os
1200
+
1154
1201
  from dreadnode.airt import Assessment
1202
+ from dreadnode.airt.assessment import _set_platform_context
1155
1203
 
1156
1204
  # Configure the SDK using the validated profile
1157
- from dreadnode.app.main import Dreadnode
1158
-
1159
- Dreadnode().configure(
1160
- server=profile.url,
1161
- api_key=profile.api_key,
1162
- organization=profile.organization,
1163
- workspace=profile.workspace,
1164
- project=profile.project,
1165
- )
1205
+ from dreadnode.app.main import DEFAULT_INSTANCE
1206
+
1207
+ env_project = os.getenv("DREADNODE_PROJECT")
1208
+ sdk_project = original_project or profile.project or env_project or "default"
1209
+
1210
+ # Try global SDK configuration first
1211
+ try:
1212
+ DEFAULT_INSTANCE.configure(
1213
+ server=profile.url,
1214
+ api_key=profile.api_key,
1215
+ organization=profile.organization,
1216
+ workspace=profile.workspace,
1217
+ project=sdk_project,
1218
+ )
1219
+ from loguru import logger
1220
+
1221
+ logger.debug("SDK instance configured successfully for assessment registration")
1222
+ except Exception as e:
1223
+ from loguru import logger
1224
+
1225
+ logger.warning(f"Failed to configure SDK instance for assessment registration: {e}")
1226
+ logger.info("Using fallback context injection for assessment registration")
1227
+
1228
+ # Always inject platform context as fallback for assessment registration
1229
+ _set_platform_context(_api, profile)
1230
+
1231
+ # Resolve project name to UUID
1232
+ # Use original CLI argument, fallback to profile, environment, then 'default'
1233
+ import os
1234
+
1235
+ env_project = os.getenv("DREADNODE_PROJECT")
1236
+ actual_project = original_project or profile.project or env_project or "default"
1237
+
1238
+ resolved_project_id = _resolve_project_id(_api, profile, actual_project)
1239
+ final_project_id = resolved_project_id or profile.project_id or actual_project
1166
1240
 
1167
1241
  async with Assessment(
1168
1242
  name=name,
@@ -1171,7 +1245,7 @@ def run(
1171
1245
  model=atk_model,
1172
1246
  goal=goal,
1173
1247
  goal_category=goal_category,
1174
- project_id=profile.project_id or profile.project,
1248
+ project_id=final_project_id,
1175
1249
  attack_defaults={
1176
1250
  "n_iterations": n_iterations,
1177
1251
  "early_stopping_score": early_stopping,
@@ -1298,13 +1372,48 @@ def run_suite(
1298
1372
  console.print(f" Config: [dim]{file}[/dim]")
1299
1373
  console.print()
1300
1374
 
1375
+ # Capture original project argument before connect() clears it
1376
+ original_project = platform.project
1377
+
1301
1378
  # Configure SDK
1302
1379
  _api, profile = platform.connect()
1303
1380
 
1304
1381
  target_fn = _build_target(model, max_tokens)
1305
1382
 
1306
1383
  async def _run_suite() -> list[dict[str, t.Any]]:
1384
+ # Determine project for SDK configuration
1385
+ # Use original CLI argument, fallback to profile, environment, then 'default'
1386
+ import os
1387
+
1307
1388
  from dreadnode.airt import Assessment
1389
+ from dreadnode.airt.assessment import _set_platform_context
1390
+
1391
+ # Configure the SDK using the validated profile
1392
+ from dreadnode.app.main import DEFAULT_INSTANCE
1393
+
1394
+ env_project = os.getenv("DREADNODE_PROJECT")
1395
+ sdk_project = original_project or profile.project or env_project or "default"
1396
+
1397
+ # Try global SDK configuration first
1398
+ try:
1399
+ DEFAULT_INSTANCE.configure(
1400
+ server=profile.url,
1401
+ api_key=profile.api_key,
1402
+ organization=profile.organization,
1403
+ workspace=profile.workspace,
1404
+ project=sdk_project,
1405
+ )
1406
+ from loguru import logger
1407
+
1408
+ logger.debug("SDK instance configured successfully for assessment registration")
1409
+ except Exception as e:
1410
+ from loguru import logger
1411
+
1412
+ logger.warning(f"Failed to configure SDK instance for assessment registration: {e}")
1413
+ logger.info("Using fallback context injection for assessment registration")
1414
+
1415
+ # Always inject platform context as fallback for assessment registration
1416
+ _set_platform_context(_api, profile)
1308
1417
 
1309
1418
  suite_results = []
1310
1419
  for i, goal_cfg in enumerate(goals, 1):
@@ -1316,6 +1425,16 @@ def run_suite(
1316
1425
 
1317
1426
  console.print(f"\n--- Goal {i}/{len(goals)}: {goal_text[:60]}...")
1318
1427
 
1428
+ # Resolve project name to UUID
1429
+ # Use original CLI argument, then environment variable as fallback
1430
+ import os
1431
+
1432
+ env_project = os.getenv("DREADNODE_PROJECT")
1433
+ actual_project = original_project or profile.project or env_project
1434
+
1435
+ resolved_project_id = _resolve_project_id(_api, profile, actual_project)
1436
+ final_project_id = resolved_project_id or profile.project_id or actual_project
1437
+
1319
1438
  async with Assessment(
1320
1439
  name=f"Suite -- {sub_cat or goal_text[:40]}",
1321
1440
  description=f"Suite run: {goal_text}",
@@ -1323,7 +1442,7 @@ def run_suite(
1323
1442
  model=atk_model,
1324
1443
  goal=goal_text,
1325
1444
  goal_category=goal_cat,
1326
- project_id=profile.project_id or profile.project,
1445
+ project_id=final_project_id,
1327
1446
  attack_defaults={
1328
1447
  "airt_category": cat,
1329
1448
  "airt_sub_category": sub_cat,
@@ -36,6 +36,14 @@ from dreadnode.app.model_catalog import resolve_model
36
36
  DEBUG = bool(os.getenv("DREADNODE_DEBUG"))
37
37
 
38
38
 
39
+ def _get_version_safe() -> str:
40
+ """Get package version safely, falling back to 'dev' if not installed."""
41
+ try:
42
+ return importlib.metadata.version("dreadnode")
43
+ except importlib.metadata.PackageNotFoundError:
44
+ return "dev"
45
+
46
+
39
47
  def _new_device_login_api_key_name() -> str:
40
48
  return f"dreadnode-{secrets.token_hex(3)}"
41
49
 
@@ -60,7 +68,7 @@ def _render_profile_context(profile: t.Any) -> str:
60
68
  cli = cyclopts.App(
61
69
  name="dreadnode",
62
70
  help="Dreadnode CLI — agent development and platform tooling.",
63
- version=importlib.metadata.version("dreadnode"),
71
+ version=_get_version_safe(),
64
72
  help_on_error=True,
65
73
  )
66
74
  cli.register_install_completion_command()
@@ -564,6 +564,42 @@ class RuntimeClient:
564
564
  response.raise_for_status()
565
565
  return response.json()
566
566
 
567
+ async def fetch_rewind_candidates(self, session_id: str) -> list[dict[str, t.Any]]:
568
+ """Return user-message rewind targets for the picker.
569
+
570
+ Returns an empty list when the runtime is not platform-synced —
571
+ rewind is platform-only, so there's nothing to surface.
572
+ """
573
+ logger.debug("Fetching rewind candidates | session_id={}", session_id[:8])
574
+ await self.start()
575
+ response = await self._http_client.get(f"/api/sessions/{session_id}/rewind/candidates")
576
+ response.raise_for_status()
577
+ body = response.json()
578
+ candidates = body.get("candidates") if isinstance(body, dict) else None
579
+ if not isinstance(candidates, list):
580
+ return []
581
+ return [entry for entry in candidates if isinstance(entry, dict)]
582
+
583
+ async def rewind_session(self, session_id: str, *, from_seq: int) -> dict[str, t.Any]:
584
+ """Hard-truncate a session at the target user-message ``seq``.
585
+
586
+ Returns ``{status, deleted_count, target_seq, restored_content}``
587
+ on success. Caller must already have aborted any in-flight turn
588
+ — the runtime refuses with ``status=skipped`` while busy.
589
+ """
590
+ logger.info(
591
+ "Rewinding session | session_id={} from_seq={}",
592
+ session_id[:8],
593
+ from_seq,
594
+ )
595
+ await self.start()
596
+ response = await self._http_client.post(
597
+ f"/api/sessions/{session_id}/rewind",
598
+ json={"from_seq": from_seq},
599
+ )
600
+ response.raise_for_status()
601
+ return dict(response.json())
602
+
567
603
  async def fetch_session_messages(self, session_id: str) -> list[dict[str, t.Any]]:
568
604
  """Fetch conversation messages for a session."""
569
605
  logger.debug("Fetching session messages | session_id={}", session_id[:8])
@@ -451,9 +451,14 @@ class Dreadnode:
451
451
 
452
452
  if self._api is not None and self._profile is not None and isinstance(project, str):
453
453
  try:
454
+ # Use configured org/workspace if available, otherwise fall back to profile
455
+ org_key = str(self.organization) if self.organization else self._profile.org_key
456
+ workspace_key = (
457
+ str(self.workspace) if self.workspace else self._profile.workspace_key
458
+ )
454
459
  resolved_project = self._api.get_project(
455
- self._profile.org_key,
456
- self._profile.workspace_key,
460
+ org_key,
461
+ workspace_key,
457
462
  project,
458
463
  )
459
464
  except RuntimeError:
@@ -1980,6 +1980,122 @@ class SessionRuntime:
1980
1980
  "messages_after": messages_after,
1981
1981
  }
1982
1982
 
1983
+ async def rewind_to(self, *, from_seq: int) -> dict[str, t.Any]:
1984
+ """Hard-truncate the session at a target user-message ``seq``.
1985
+
1986
+ Calls the platform rewind endpoint, then re-fetches the truncated
1987
+ transcript and replaces the in-memory trajectory so the next chat
1988
+ turn won't replay the deleted messages as model context.
1989
+
1990
+ Returns a dict with ``status`` (``completed`` | ``skipped`` |
1991
+ ``failed``), and on success ``deleted_count`` / ``target_seq`` /
1992
+ ``restored_content`` echoed straight from the platform response.
1993
+
1994
+ Refuses when the session is busy (an in-flight turn would race
1995
+ with the truncate); the caller is expected to send ``/cancel``
1996
+ first and wait for the abort to settle. Refuses when the session
1997
+ isn't synced to a platform — there's no in-memory-only rewind
1998
+ primitive to fall back to (no marker, no shadow tree).
1999
+ """
2000
+ if self.is_busy:
2001
+ return {"status": "skipped", "reason": "turn_in_progress"}
2002
+
2003
+ ctx = self._get_api_context()
2004
+ if ctx is None:
2005
+ return {"status": "failed", "reason": "no_platform_sync"}
2006
+ api, org, ws = ctx
2007
+
2008
+ try:
2009
+ result = await asyncio.to_thread(
2010
+ api.rewind_transcript,
2011
+ org,
2012
+ ws,
2013
+ self.session_id,
2014
+ from_seq=from_seq,
2015
+ )
2016
+ except Exception as exc:
2017
+ logger.warning(
2018
+ "Rewind failed at platform | session={} from_seq={} error={}",
2019
+ self.session_id[:8],
2020
+ from_seq,
2021
+ exc,
2022
+ )
2023
+ return {"status": "failed", "reason": str(exc)}
2024
+
2025
+ # Re-source the in-memory trajectory from the platform's truncated
2026
+ # transcript. ``restore_messages`` rebuilds via OpenAI-format
2027
+ # conversion, which loses event-type granularity (GenerationStep
2028
+ # vs ToolStep) — that's fine here: rewind is destructive, the
2029
+ # next turn re-derives event detail from the model's response.
2030
+ try:
2031
+ transcript = await asyncio.to_thread(
2032
+ api.get_transcript,
2033
+ org,
2034
+ ws,
2035
+ self.session_id,
2036
+ )
2037
+ except Exception:
2038
+ logger.opt(exception=True).warning(
2039
+ "Rewind succeeded on platform but transcript refetch failed | session={}",
2040
+ self.session_id[:8],
2041
+ )
2042
+ transcript = {"messages": []}
2043
+
2044
+ rebuilt: list[SessionMessage] = []
2045
+ for raw in transcript.get("messages") or []:
2046
+ role = raw.get("role")
2047
+ content = raw.get("content") or ""
2048
+ if role in {"user", "assistant"} and isinstance(content, str):
2049
+ rebuilt.append(SessionMessage(role=role, content=content))
2050
+
2051
+ self.restore_messages(rebuilt, persist=False)
2052
+ self.persistence.persisted_message_count = len(self._trajectory.messages)
2053
+
2054
+ return {
2055
+ "status": "completed",
2056
+ "deleted_count": int(result.get("deleted_count") or 0),
2057
+ "target_seq": int(result.get("target_seq") or from_seq),
2058
+ "restored_content": str(result.get("restored_content") or ""),
2059
+ }
2060
+
2061
+ def list_rewind_candidates(self) -> dict[str, t.Any]:
2062
+ """Return user-message rewind targets for the picker.
2063
+
2064
+ Pulls non-compacted ``role='user'`` rows straight from the
2065
+ platform's transcript so the picker shows the same seqs the
2066
+ rewind endpoint accepts. Sessions without platform sync (offline
2067
+ runtime) return an empty list — there's no rewindable history
2068
+ to surface.
2069
+ """
2070
+ ctx = self._get_api_context()
2071
+ if ctx is None:
2072
+ return {"status": "unavailable", "reason": "no_platform_sync", "candidates": []}
2073
+ api, org, ws = ctx
2074
+
2075
+ try:
2076
+ transcript = api.get_transcript(org, ws, self.session_id)
2077
+ except Exception as exc:
2078
+ logger.opt(exception=True).debug("Failed to load rewind candidates")
2079
+ return {"status": "failed", "reason": str(exc), "candidates": []}
2080
+
2081
+ candidates: list[dict[str, t.Any]] = []
2082
+ for raw in transcript.get("messages") or []:
2083
+ if raw.get("role") != "user":
2084
+ continue
2085
+ if raw.get("compacted_at") is not None:
2086
+ continue
2087
+ content = raw.get("content")
2088
+ if not isinstance(content, str):
2089
+ continue
2090
+ candidates.append(
2091
+ {
2092
+ "seq": int(raw.get("seq") or 0),
2093
+ "content": content,
2094
+ "created_at": raw.get("created_at"),
2095
+ }
2096
+ )
2097
+ return {"status": "ok", "candidates": candidates}
2098
+
1983
2099
  def _compact_transcript_on_api(
1984
2100
  self,
1985
2101
  boundary: int,
@@ -2102,15 +2218,14 @@ class SessionRuntime:
2102
2218
  model: str | None = None,
2103
2219
  persist: bool = True,
2104
2220
  ) -> None:
2105
- """Seed the session agent trajectory from a simple message list."""
2106
- from dreadnode.agents.trajectory import trajectory_from_openai_format
2221
+ """Seed the session agent trajectory from a simple message list.
2107
2222
 
2108
- if not messages:
2109
- if model is not None:
2110
- self.model = model
2111
- if persist:
2112
- self._persist_state(update_messages=False)
2113
- return
2223
+ An empty ``messages`` list resets the trajectory to a fresh empty
2224
+ state the rewind-to-seq-0 path relies on this to clear the
2225
+ in-memory transcript after the platform truncates everything
2226
+ (`ENG-6776`). Other callers guard against empty input upstream.
2227
+ """
2228
+ from dreadnode.agents.trajectory import trajectory_from_openai_format
2114
2229
 
2115
2230
  if model is not None:
2116
2231
  self.model = model
@@ -3139,6 +3254,36 @@ async def compact_session(session_id: str, body: dict[str, t.Any] | None = None)
3139
3254
  return JSONResponse(content=result)
3140
3255
 
3141
3256
 
3257
+ @app.get("/api/sessions/{session_id}/rewind/candidates")
3258
+ async def list_rewind_candidates(session_id: str) -> JSONResponse:
3259
+ """Return user-message rewind targets pulled from platform-side transcript.
3260
+
3261
+ The picker uses this rather than the runtime's in-memory trajectory
3262
+ because seqs only exist on the platform side; the in-memory copy
3263
+ does not track them.
3264
+ """
3265
+ session = get_state().get_session(session_id)
3266
+ if session is None:
3267
+ raise HTTPException(status_code=404, detail=f"Session not found: {session_id}")
3268
+ return JSONResponse(content=await asyncio.to_thread(session.list_rewind_candidates))
3269
+
3270
+
3271
+ @app.post("/api/sessions/{session_id}/rewind")
3272
+ async def rewind_session(session_id: str, body: dict[str, t.Any]) -> JSONResponse:
3273
+ """Hard-truncate a session's transcript at a target user-message seq."""
3274
+ session = get_state().get_session(session_id)
3275
+ if session is None:
3276
+ raise HTTPException(status_code=404, detail=f"Session not found: {session_id}")
3277
+ raw_seq = body.get("from_seq")
3278
+ if not isinstance(raw_seq, int) or raw_seq < 0:
3279
+ raise HTTPException(
3280
+ status_code=422,
3281
+ detail="from_seq must be a non-negative integer",
3282
+ )
3283
+ result = await session.rewind_to(from_seq=raw_seq)
3284
+ return JSONResponse(content=result)
3285
+
3286
+
3142
3287
  # =============================================================================
3143
3288
  # File & Shell Endpoints
3144
3289
  # =============================================================================
@@ -3771,7 +3916,32 @@ def _populate_registry(instance: t.Any) -> None:
3771
3916
  # 2. Determine host type: sandbox if runtime binding env is set, local otherwise
3772
3917
  host = "sandbox" if os.environ.get("DREADNODE_RUNTIME_ID", "").strip() else "local"
3773
3918
 
3774
- # 3. Discover with host-exclusive source (CAP-LOAD-014)
3919
+ # 3. Install declared dependencies before discovery so preflight `checks:`
3920
+ # see installed binaries. Failures log loudly but never block load —
3921
+ # `checks:` is the user-visible signal for unmet prerequisites.
3922
+ if host == "sandbox" and workspace_dir is not None:
3923
+ try:
3924
+ from dreadnode.capabilities.install import install_dependencies
3925
+ from dreadnode.capabilities.loader import preload_dependency_specs
3926
+
3927
+ install_specs = preload_dependency_specs(workspace_dir)
3928
+ install_report = install_dependencies(install_specs)
3929
+ if install_report.installed:
3930
+ logger.info(
3931
+ "Installed dependencies for {} capabilities: {}",
3932
+ len(install_report.installed),
3933
+ install_report.installed,
3934
+ )
3935
+ if install_report.cached:
3936
+ logger.debug("Skipped install (already cached) for: {}", install_report.cached)
3937
+ for cap_name, error in install_report.failed.items():
3938
+ logger.error("Dependency install failed for capability '{}': {}", cap_name, error)
3939
+ except Exception:
3940
+ logger.opt(exception=True).warning(
3941
+ "Capability dependency install pass failed; continuing with discovery"
3942
+ )
3943
+
3944
+ # 4. Discover with host-exclusive source (CAP-LOAD-014)
3775
3945
  try:
3776
3946
  result = Capability.discover(
3777
3947
  cwd=Path.cwd(),