dreadnode 2.0.17__tar.gz → 2.0.19__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 (623) hide show
  1. {dreadnode-2.0.17 → dreadnode-2.0.19}/PKG-INFO +2 -2
  2. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/agents/__init__.py +12 -0
  3. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/agents/hooks.py +252 -1
  4. dreadnode-2.0.19/dreadnode/agents/process_judge.py +212 -0
  5. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/api/client.py +84 -15
  6. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/api/models.py +2 -0
  7. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/args.py +16 -0
  8. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/main.py +86 -1
  9. dreadnode-2.0.19/dreadnode/app/cli/session.py +677 -0
  10. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/shared.py +5 -1
  11. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/server/app.py +54 -69
  12. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/server/capability_manager.py +5 -5
  13. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/app.py +1 -1
  14. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/error_handler.py +10 -0
  15. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/model_manager.py +7 -0
  16. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/screens/base.py +18 -0
  17. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/screens/capabilities.py +16 -1
  18. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/screens/environments.py +14 -2
  19. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/screens/models.py +156 -105
  20. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/screens/runtimes.py +16 -1
  21. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/screens/sessions.py +14 -1
  22. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/screens/workspaces.py +16 -1
  23. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/update_check.py +11 -3
  24. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/INDEX.md +2 -0
  25. dreadnode-2.0.19/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/hooks.md +220 -0
  26. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/manifest.md +14 -7
  27. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/overview.md +1 -0
  28. dreadnode-2.0.19/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/policies.md +169 -0
  29. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/sdk/agents.md +29 -0
  30. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/main.md +15 -1
  31. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/capabilities/overview.md +1 -0
  32. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/capabilities/loader.py +9 -8
  33. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/hook.py +22 -44
  34. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/optimization/adapters/stack.py +4 -4
  35. dreadnode-2.0.19/dreadnode/policies/__init__.py +229 -0
  36. dreadnode-2.0.19/dreadnode/policies/guard.py +154 -0
  37. dreadnode-2.0.19/dreadnode/policies/rubrics/process/default.yaml +38 -0
  38. {dreadnode-2.0.17 → dreadnode-2.0.19}/pyproject.toml +2 -2
  39. dreadnode-2.0.17/dreadnode/app/server/session_policy.py +0 -425
  40. {dreadnode-2.0.17 → dreadnode-2.0.19}/.gitignore +0 -0
  41. {dreadnode-2.0.17 → dreadnode-2.0.19}/LICENSE +0 -0
  42. {dreadnode-2.0.17 → dreadnode-2.0.19}/README.md +0 -0
  43. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/__init__.py +0 -0
  44. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/__main__.py +0 -0
  45. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/agents/agent.py +0 -0
  46. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/agents/events.py +0 -0
  47. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/agents/exceptions.py +0 -0
  48. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/agents/format.py +0 -0
  49. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/agents/judge.py +0 -0
  50. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/agents/mcp/__init__.py +0 -0
  51. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/agents/mcp/auth.py +0 -0
  52. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/agents/mcp/client.py +0 -0
  53. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/agents/mcp/config.py +0 -0
  54. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/agents/mcp/server.py +0 -0
  55. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/agents/reactions.py +0 -0
  56. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/agents/skills.py +0 -0
  57. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/agents/stopping.py +0 -0
  58. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/agents/subagent.py +0 -0
  59. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/agents/tool_resolution.py +0 -0
  60. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/agents/tools.py +0 -0
  61. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/agents/trajectory.py +0 -0
  62. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/__init__.py +0 -0
  63. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/adversarial_reasoning.py +0 -0
  64. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/advpromptier.py +0 -0
  65. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/alignment_faking.py +0 -0
  66. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/analogy_escalation.py +0 -0
  67. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/analytics/__init__.py +0 -0
  68. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/analytics/aggregator.py +0 -0
  69. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/analytics/classifier.py +0 -0
  70. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/analytics/compliance.py +0 -0
  71. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/analytics/engine.py +0 -0
  72. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/analytics/recommendations.py +0 -0
  73. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/analytics/types.py +0 -0
  74. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/aprt_progressive.py +0 -0
  75. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/assessment.py +0 -0
  76. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/attention_shifting.py +0 -0
  77. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/autodan_turbo.py +0 -0
  78. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/autoredteamer.py +0 -0
  79. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/beast.py +0 -0
  80. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/compliance/__init__.py +0 -0
  81. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/compliance/atlas.py +0 -0
  82. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/compliance/nist.py +0 -0
  83. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/compliance/owasp.py +0 -0
  84. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/compliance/owasp_agentic.py +0 -0
  85. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/compliance/saif.py +0 -0
  86. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/constants.py +0 -0
  87. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/cot_jailbreak.py +0 -0
  88. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/crescendo.py +0 -0
  89. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/data/__init__.py +0 -0
  90. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/data/assets/audio/adversarial_query.mp3 +0 -0
  91. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/data/assets/image/bomb.jpg +0 -0
  92. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/data/assets/image/meth.png +0 -0
  93. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/data/prompts/adversarial_benchmark_subset.csv +0 -0
  94. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/data/prompts/ai_safety.csv +0 -0
  95. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/data/rubrics/data_exfiltration.yaml +0 -0
  96. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/data/rubrics/goal_hijacking.yaml +0 -0
  97. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/data/rubrics/memory_poisoning.yaml +0 -0
  98. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/data/rubrics/privilege_escalation.yaml +0 -0
  99. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/data/rubrics/rce.yaml +0 -0
  100. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/data/rubrics/scope_creep.yaml +0 -0
  101. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/data/rubrics/tool_chaining.yaml +0 -0
  102. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/data/rubrics/tool_selection_safety.yaml +0 -0
  103. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/data/rubrics/unbounded_agency.yaml +0 -0
  104. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/data/rubrics/web_chatbot_security.yaml +0 -0
  105. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/data/templates/crescendo/variant_1.yaml +0 -0
  106. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/data/templates/crescendo/variant_2.yaml +0 -0
  107. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/data/templates/crescendo/variant_3.yaml +0 -0
  108. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/data/templates/crescendo/variant_4.yaml +0 -0
  109. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/data/templates/crescendo/variant_5.yaml +0 -0
  110. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/deep_inception.py +0 -0
  111. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/drattack.py +0 -0
  112. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/echo_chamber.py +0 -0
  113. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/events.py +0 -0
  114. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/genetic_persona.py +0 -0
  115. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/goat.py +0 -0
  116. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/goat_v2.py +0 -0
  117. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/gptfuzzer.py +0 -0
  118. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/humor_bypass.py +0 -0
  119. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/image.py +0 -0
  120. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/j2_meta.py +0 -0
  121. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/jbdistill.py +0 -0
  122. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/jbfuzz.py +0 -0
  123. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/lrm_autonomous.py +0 -0
  124. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/mapf.py +0 -0
  125. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/multimodal.py +0 -0
  126. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/nexus.py +0 -0
  127. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/pair.py +0 -0
  128. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/persona_hijack.py +0 -0
  129. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/prompt.py +0 -0
  130. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/quantization_safety.py +0 -0
  131. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/rainbow.py +0 -0
  132. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/refusal_aware.py +0 -0
  133. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/renellm.py +0 -0
  134. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/reporting/__init__.py +0 -0
  135. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/reporting/json_report.py +0 -0
  136. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/reporting/llm_summary.py +0 -0
  137. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/reporting/markdown.py +0 -0
  138. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/reward_hacking.py +0 -0
  139. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/salami_slicing.py +0 -0
  140. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/self_persuasion.py +0 -0
  141. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/siren.py +0 -0
  142. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/tap.py +0 -0
  143. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/templatefuzz.py +0 -0
  144. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/tmap_trajectory.py +0 -0
  145. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/trojail.py +0 -0
  146. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/airt/watermark_removal.py +0 -0
  147. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/__init__.py +0 -0
  148. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/api/__init__.py +0 -0
  149. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/__init__.py +0 -0
  150. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/airt.py +0 -0
  151. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/capability.py +0 -0
  152. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/dataset.py +0 -0
  153. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/environment.py +0 -0
  154. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/evaluation.py +0 -0
  155. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/inference_model.py +0 -0
  156. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/model.py +0 -0
  157. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/optimize.py +0 -0
  158. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/runtime.py +0 -0
  159. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/sandbox.py +0 -0
  160. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/secret.py +0 -0
  161. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/task.py +0 -0
  162. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/templates/__init__.py +0 -0
  163. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/templates/init/__init__.py +0 -0
  164. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/templates/init/challenge/Dockerfile +0 -0
  165. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/templates/init/docker-compose.yaml +0 -0
  166. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/templates/init/provision.sh +0 -0
  167. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/templates/init/solution.sh +0 -0
  168. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/templates/init/task-remote.yaml.tmpl +0 -0
  169. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/templates/init/task.yaml.tmpl +0 -0
  170. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/templates/init/teardown.sh +0 -0
  171. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/templates/init/verify.sh +0 -0
  172. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/train.py +0 -0
  173. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/cli/worlds.py +0 -0
  174. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/client/__init__.py +0 -0
  175. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/client/interactive.py +0 -0
  176. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/client/managed_client.py +0 -0
  177. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/client/models.py +0 -0
  178. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/client/runtime_client.py +0 -0
  179. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/client/transports.py +0 -0
  180. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/config.py +0 -0
  181. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/env.py +0 -0
  182. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/main.py +0 -0
  183. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/model_catalog.py +0 -0
  184. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/paths.py +0 -0
  185. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/print_mode.py +0 -0
  186. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/server/__init__.py +0 -0
  187. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/server/auth.py +0 -0
  188. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/server/model_resolution.py +0 -0
  189. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/server/prompt.py +0 -0
  190. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/server/prompt_registry.py +0 -0
  191. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/server/runtime_events.py +0 -0
  192. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/server/session_hydrator.py +0 -0
  193. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/server/session_persistence.py +0 -0
  194. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/server/turn_coordinator.py +0 -0
  195. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/server/utils.py +0 -0
  196. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/server/websocket.py +0 -0
  197. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/server/worker_manager.py +0 -0
  198. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/__init__.py +0 -0
  199. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/auth_flow.py +0 -0
  200. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/capabilities_manager.py +0 -0
  201. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/command_dispatcher.py +0 -0
  202. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/commands.py +0 -0
  203. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/connection.py +0 -0
  204. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/dreadnode.tcss +0 -0
  205. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/model_variants.py +0 -0
  206. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/profile_manager.py +0 -0
  207. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/runtime_cache.py +0 -0
  208. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/screen_router.py +0 -0
  209. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/screens/__init__.py +0 -0
  210. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/screens/auth.py +0 -0
  211. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/screens/capability_docs.py +0 -0
  212. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/screens/connection_error.py +0 -0
  213. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/screens/console.py +0 -0
  214. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/screens/evaluations.py +0 -0
  215. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/screens/model_picker.py +0 -0
  216. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/screens/raw_spans.py +0 -0
  217. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/screens/sandboxes.py +0 -0
  218. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/screens/secrets.py +0 -0
  219. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/screens/services.py +0 -0
  220. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/screens/theme_showcase.py +0 -0
  221. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/screens/traces.py +0 -0
  222. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/sessions_manager.py +0 -0
  223. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/spans_reader.py +0 -0
  224. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/status_messages.py +0 -0
  225. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/theme.py +0 -0
  226. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/tool_format.py +0 -0
  227. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/turn_coordinator.py +0 -0
  228. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/turn_lifecycle.py +0 -0
  229. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/turn_reducer.py +0 -0
  230. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/turn_state_phase.py +0 -0
  231. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/__init__.py +0 -0
  232. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/agent_dialog.py +0 -0
  233. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/agent_suggester.py +0 -0
  234. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/composer.py +0 -0
  235. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/confirm_modal.py +0 -0
  236. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/context_bar.py +0 -0
  237. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/conversation.py +0 -0
  238. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/flash.py +0 -0
  239. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/header_bar.py +0 -0
  240. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/help_panel.py +0 -0
  241. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/human_prompt.py +0 -0
  242. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/mention_overlay.py +0 -0
  243. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/message_queue.py +0 -0
  244. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/new_messages_pill.py +0 -0
  245. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/overlay_mixin.py +0 -0
  246. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/permission_prompt.py +0 -0
  247. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/profile_dialog.py +0 -0
  248. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/prompt_info.py +0 -0
  249. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/session_sidebar.py +0 -0
  250. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/skills_dialog.py +0 -0
  251. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/slash_overlay.py +0 -0
  252. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/status_bar.py +0 -0
  253. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/throbber.py +0 -0
  254. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/tool.py +0 -0
  255. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/tool_progress.py +0 -0
  256. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/tools_dialog.py +0 -0
  257. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/welcome.py +0 -0
  258. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/widgets/whoami.py +0 -0
  259. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/app/tui/wire_events.py +0 -0
  260. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/__init__.py +0 -0
  261. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/MAINTAINING.md +0 -0
  262. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/agents/dreadnode.md +0 -0
  263. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/capability.yaml +0 -0
  264. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/SKILL.md +0 -0
  265. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/capability-improvement.md +0 -0
  266. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/promoting-capabilities.md +0 -0
  267. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/agents.md +0 -0
  268. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/dependencies-and-checks.md +0 -0
  269. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/env-vars.md +0 -0
  270. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/events.md +0 -0
  271. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/flags.md +0 -0
  272. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/installing.md +0 -0
  273. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/mcp-servers.md +0 -0
  274. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/publishing.md +0 -0
  275. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/quickstart.md +0 -0
  276. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/skills.md +0 -0
  277. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/tools.md +0 -0
  278. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/workers-reference.md +0 -0
  279. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/workers.md +0 -0
  280. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/writing-skills.md +0 -0
  281. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/guides/capability-optimization-loop.md +0 -0
  282. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/sdk/capabilities.md +0 -0
  283. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/tui/default-tools.md +0 -0
  284. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/runtime-default-capability.md +0 -0
  285. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/SKILL.md +0 -0
  286. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/INDEX.md +0 -0
  287. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/airt.md +0 -0
  288. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/capability.md +0 -0
  289. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/dataset.md +0 -0
  290. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/env.md +0 -0
  291. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/evaluation.md +0 -0
  292. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/inference-model.md +0 -0
  293. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/model.md +0 -0
  294. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/optimize.md +0 -0
  295. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/overview.md +0 -0
  296. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/runtime.md +0 -0
  297. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/sandbox.md +0 -0
  298. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/secret.md +0 -0
  299. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/task.md +0 -0
  300. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/train.md +0 -0
  301. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/worlds.md +0 -0
  302. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/getting-started/authentication.md +0 -0
  303. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/SKILL.md +0 -0
  304. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/INDEX.md +0 -0
  305. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/capabilities/installing.md +0 -0
  306. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/getting-started/authentication.md +0 -0
  307. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/getting-started/overview.md +0 -0
  308. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/getting-started/quickstart.md +0 -0
  309. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/chat-models.md +0 -0
  310. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/credits.md +0 -0
  311. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/organizations.md +0 -0
  312. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/overview.md +0 -0
  313. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/projects.md +0 -0
  314. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/secrets.md +0 -0
  315. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/settings.md +0 -0
  316. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/users.md +0 -0
  317. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/workspaces.md +0 -0
  318. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/configuration.md +0 -0
  319. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/managing.md +0 -0
  320. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/manifest-reference.md +0 -0
  321. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/overview.md +0 -0
  322. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/quickstart.md +0 -0
  323. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/serve.md +0 -0
  324. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/sandboxes/environment-lifecycle.md +0 -0
  325. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/sandboxes/inspecting.md +0 -0
  326. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/sandboxes/overview.md +0 -0
  327. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/getting-started/SKILL.md +0 -0
  328. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/dreadnode/skills/research-capabilities/SKILL.md +0 -0
  329. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/self-improvement/.gitignore +0 -0
  330. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/self-improvement/capability.yaml +0 -0
  331. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/self-improvement/hooks/__init__.py +0 -0
  332. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/self-improvement/hooks/observer.py +0 -0
  333. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/__init__.py +0 -0
  334. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/classifier.py +0 -0
  335. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/reflector_goal.py +0 -0
  336. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/skill_io.py +0 -0
  337. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/self-improvement/skills-promoted/.gitkeep +0 -0
  338. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/self-improvement/skills-proposed/.gitkeep +0 -0
  339. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/self-improvement/tools/__init__.py +0 -0
  340. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/self-improvement/tools/reflector.py +0 -0
  341. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/builtin_capabilities/self-improvement/tools/skill_stats.py +0 -0
  342. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/capabilities/__init__.py +0 -0
  343. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/capabilities/capability.py +0 -0
  344. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/capabilities/flags.py +0 -0
  345. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/capabilities/sync.py +0 -0
  346. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/capabilities/tool_rules.py +0 -0
  347. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/capabilities/types.py +0 -0
  348. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/capabilities/worker.py +0 -0
  349. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/capabilities/worker_runner.py +0 -0
  350. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/__init__.py +0 -0
  351. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/conditions.py +0 -0
  352. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/discovery.py +0 -0
  353. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/environment.py +0 -0
  354. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/exceptions.py +0 -0
  355. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/execution.py +0 -0
  356. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/judge.py +0 -0
  357. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/load.py +0 -0
  358. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/log.py +0 -0
  359. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/meta/__init__.py +0 -0
  360. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/meta/config.py +0 -0
  361. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/meta/context.py +0 -0
  362. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/meta/hydrate.py +0 -0
  363. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/meta/introspect.py +0 -0
  364. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/metric.py +0 -0
  365. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/object.py +0 -0
  366. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/scorer.py +0 -0
  367. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/serialization.py +0 -0
  368. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/stopping.py +0 -0
  369. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/task.py +0 -0
  370. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/templating.py +0 -0
  371. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/transforms.py +0 -0
  372. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/types/__init__.py +0 -0
  373. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/types/audio.py +0 -0
  374. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/types/base.py +0 -0
  375. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/types/common.py +0 -0
  376. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/types/image.py +0 -0
  377. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/types/object_3d.py +0 -0
  378. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/types/table.py +0 -0
  379. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/types/text.py +0 -0
  380. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/types/video.py +0 -0
  381. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/core/util.py +0 -0
  382. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/datasets/__init__.py +0 -0
  383. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/datasets/dataset.py +0 -0
  384. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/datasets/hf.py +0 -0
  385. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/datasets/local.py +0 -0
  386. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/evaluations/__init__.py +0 -0
  387. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/evaluations/console.py +0 -0
  388. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/evaluations/evaluation.py +0 -0
  389. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/evaluations/events.py +0 -0
  390. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/evaluations/format.py +0 -0
  391. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/evaluations/result.py +0 -0
  392. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/evaluations/sample.py +0 -0
  393. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/generators/__init__.py +0 -0
  394. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/generators/caching.py +0 -0
  395. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/generators/chat.py +0 -0
  396. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/generators/data.py +0 -0
  397. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/generators/exceptions.py +0 -0
  398. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/generators/generator/__init__.py +0 -0
  399. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/generators/generator/base.py +0 -0
  400. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/generators/generator/http.py +0 -0
  401. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/generators/generator/litellm_.py +0 -0
  402. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/generators/generator/transformers_.py +0 -0
  403. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/generators/generator/vllm_.py +0 -0
  404. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/generators/message.py +0 -0
  405. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/generators/models.py +0 -0
  406. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/generators/parsing.py +0 -0
  407. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/generators/tokenizer/__init__.py +0 -0
  408. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/generators/tokenizer/base.py +0 -0
  409. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/generators/tokenizer/transformers_.py +0 -0
  410. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/generators/utils.py +0 -0
  411. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/models/__init__.py +0 -0
  412. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/models/hf.py +0 -0
  413. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/models/local.py +0 -0
  414. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/models/model.py +0 -0
  415. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/optimization/__init__.py +0 -0
  416. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/optimization/adapters/__init__.py +0 -0
  417. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/optimization/adapters/_env_eval.py +0 -0
  418. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/optimization/adapters/agent.py +0 -0
  419. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/optimization/adapters/env.py +0 -0
  420. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/optimization/adapters/runtime.py +0 -0
  421. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/optimization/api.py +0 -0
  422. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/optimization/backends/__init__.py +0 -0
  423. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/optimization/backends/base.py +0 -0
  424. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/optimization/backends/gepa.py +0 -0
  425. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/optimization/collectors.py +0 -0
  426. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/optimization/config.py +0 -0
  427. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/optimization/console.py +0 -0
  428. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/optimization/events.py +0 -0
  429. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/optimization/format.py +0 -0
  430. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/optimization/jobs.py +0 -0
  431. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/optimization/result.py +0 -0
  432. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/optimization/sampler.py +0 -0
  433. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/optimization/sampling.py +0 -0
  434. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/optimization/search.py +0 -0
  435. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/optimization/stopping.py +0 -0
  436. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/optimization/study.py +0 -0
  437. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/optimization/trial.py +0 -0
  438. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/packaging/__init__.py +0 -0
  439. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/packaging/loader.py +0 -0
  440. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/packaging/manifest.py +0 -0
  441. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/packaging/oci.py +0 -0
  442. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/packaging/package.py +0 -0
  443. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/packaging/task_validation.py +0 -0
  444. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/py.typed +0 -0
  445. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/samplers/__init__.py +0 -0
  446. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/samplers/boundary.py +0 -0
  447. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/samplers/fuzzing.py +0 -0
  448. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/samplers/graph.py +0 -0
  449. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/samplers/grid.py +0 -0
  450. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/samplers/image.py +0 -0
  451. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/samplers/mapelites.py +0 -0
  452. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/samplers/optuna.py +0 -0
  453. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/samplers/random.py +0 -0
  454. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/samplers/registry.py +0 -0
  455. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/samplers/strategy.py +0 -0
  456. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/__init__.py +0 -0
  457. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/advanced_jailbreak_detection.py +0 -0
  458. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/agent_security.py +0 -0
  459. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/agentic.py +0 -0
  460. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/agentic_workflow.py +0 -0
  461. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/attack_outcome.py +0 -0
  462. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/classification.py +0 -0
  463. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/consistency.py +0 -0
  464. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/contains.py +0 -0
  465. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/cosine_sim.py +0 -0
  466. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/credentials.py +0 -0
  467. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/crucible.py +0 -0
  468. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/documentation_security.py +0 -0
  469. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/exfiltration_detection.py +0 -0
  470. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/format.py +0 -0
  471. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/harm.py +0 -0
  472. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/ide_security.py +0 -0
  473. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/image.py +0 -0
  474. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/json.py +0 -0
  475. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/judge.py +0 -0
  476. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/judge_ensemble.py +0 -0
  477. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/length.py +0 -0
  478. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/lexical.py +0 -0
  479. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/mcp_security.py +0 -0
  480. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/memorization.py +0 -0
  481. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/multi_agent_security.py +0 -0
  482. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/pii.py +0 -0
  483. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/prompt_leak.py +0 -0
  484. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/readability.py +0 -0
  485. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/reasoning_security.py +0 -0
  486. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/sentiment.py +0 -0
  487. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/similarity.py +0 -0
  488. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/structural_detection.py +0 -0
  489. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/scorers/supply_chain_detection.py +0 -0
  490. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/storage/__init__.py +0 -0
  491. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/storage/providers.py +0 -0
  492. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/storage/session_store.py +0 -0
  493. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/storage/storage.py +0 -0
  494. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tools/__init__.py +0 -0
  495. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tools/_ripgrep.py +0 -0
  496. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tools/apply_patch.py +0 -0
  497. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tools/dreadnode_cli.py +0 -0
  498. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tools/editing.py +0 -0
  499. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tools/execute.py +0 -0
  500. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tools/fetch.py +0 -0
  501. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tools/glob.py +0 -0
  502. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tools/grep.py +0 -0
  503. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tools/interaction.py +0 -0
  504. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tools/ls.py +0 -0
  505. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tools/memory.py +0 -0
  506. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tools/read.py +0 -0
  507. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tools/report.py +0 -0
  508. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tools/task.py +0 -0
  509. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tools/think.py +0 -0
  510. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tools/todo.py +0 -0
  511. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tools/trajectory_search.py +0 -0
  512. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tools/web_extract.py +0 -0
  513. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tools/web_search.py +0 -0
  514. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tools/write.py +0 -0
  515. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tracing/__init__.py +0 -0
  516. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tracing/constants.py +0 -0
  517. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tracing/convert.py +0 -0
  518. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tracing/exporter.py +0 -0
  519. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tracing/exporters.py +0 -0
  520. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tracing/span.py +0 -0
  521. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tracing/spans.py +0 -0
  522. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/tracing/trace_converter.py +0 -0
  523. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/__init__.py +0 -0
  524. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/_progress.py +0 -0
  525. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/base.py +0 -0
  526. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/dpo.py +0 -0
  527. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/env_rollouts.py +0 -0
  528. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/etl/__init__.py +0 -0
  529. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/etl/_common.py +0 -0
  530. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/etl/rl.py +0 -0
  531. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/etl/sft.py +0 -0
  532. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/etl/worlds.py +0 -0
  533. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/events.py +0 -0
  534. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/grpo.py +0 -0
  535. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/jobs.py +0 -0
  536. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/models.py +0 -0
  537. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/ppo.py +0 -0
  538. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/prime.py +0 -0
  539. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/ray/__init__.py +0 -0
  540. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/ray/async_trainer.py +0 -0
  541. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/ray/config.py +0 -0
  542. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/ray/coordinator.py +0 -0
  543. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/ray/distributed.py +0 -0
  544. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/ray/dpo.py +0 -0
  545. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/ray/experience.py +0 -0
  546. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/ray/fsdp2_learner.py +0 -0
  547. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/ray/inference.py +0 -0
  548. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/ray/learner.py +0 -0
  549. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/ray/multi_turn.py +0 -0
  550. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/ray/ppo.py +0 -0
  551. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/ray/reward_model.py +0 -0
  552. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/ray/rollout_env.py +0 -0
  553. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/ray/rollout_worker.py +0 -0
  554. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/ray/sft.py +0 -0
  555. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/ray/trainer.py +0 -0
  556. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/recipes.py +0 -0
  557. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/rewards/__init__.py +0 -0
  558. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/rewards/aggregator.py +0 -0
  559. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/rewards/functions.py +0 -0
  560. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/rewards/scorer_bridge.py +0 -0
  561. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/rewards/shaping.py +0 -0
  562. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/rewards/types.py +0 -0
  563. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/rollouts/__init__.py +0 -0
  564. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/rollouts/adapters.py +0 -0
  565. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/rollouts/agent_rollout.py +0 -0
  566. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/rollouts/orchestrator.py +0 -0
  567. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/rollouts/types.py +0 -0
  568. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/rollouts/worlds.py +0 -0
  569. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/serving/__init__.py +0 -0
  570. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/serving/vllm_client.py +0 -0
  571. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/sft.py +0 -0
  572. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/tinker/__init__.py +0 -0
  573. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/tinker/config.py +0 -0
  574. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/tinker/data.py +0 -0
  575. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/tinker/renderer.py +0 -0
  576. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/tinker/rl.py +0 -0
  577. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/tinker/trainer.py +0 -0
  578. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/tinker_sft.py +0 -0
  579. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/training/utils.py +0 -0
  580. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/__init__.py +0 -0
  581. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/advanced_jailbreak.py +0 -0
  582. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/adversarial_suffix.py +0 -0
  583. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/agent_skill.py +0 -0
  584. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/agentic_workflow.py +0 -0
  585. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/audio.py +0 -0
  586. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/backdoor_finetune.py +0 -0
  587. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/browser_agent_attacks.py +0 -0
  588. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/cipher.py +0 -0
  589. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/competitive_parity.py +0 -0
  590. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/constitutional.py +0 -0
  591. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/document.py +0 -0
  592. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/documentation_poison.py +0 -0
  593. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/encoding.py +0 -0
  594. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/exfiltration.py +0 -0
  595. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/flip_attack.py +0 -0
  596. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/guardrail_bypass.py +0 -0
  597. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/ide_injection.py +0 -0
  598. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/image.py +0 -0
  599. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/injection.py +0 -0
  600. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/json_tools.py +0 -0
  601. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/language.py +0 -0
  602. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/logic_bomb.py +0 -0
  603. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/mcp_attacks.py +0 -0
  604. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/multi_agent_attacks.py +0 -0
  605. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/multimodal_attacks.py +0 -0
  606. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/persuasion.py +0 -0
  607. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/perturbation.py +0 -0
  608. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/pii_extraction.py +0 -0
  609. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/pythonic_tools.py +0 -0
  610. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/rag_poisoning.py +0 -0
  611. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/reasoning_attacks.py +0 -0
  612. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/refine.py +0 -0
  613. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/response_steering.py +0 -0
  614. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/structural_exploits.py +0 -0
  615. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/stylistic.py +0 -0
  616. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/substitution.py +0 -0
  617. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/supply_chain.py +0 -0
  618. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/swap.py +0 -0
  619. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/system_prompt_extraction.py +0 -0
  620. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/text.py +0 -0
  621. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/video.py +0 -0
  622. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/transforms/xml_tools.py +0 -0
  623. {dreadnode-2.0.17 → dreadnode-2.0.19}/dreadnode/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dreadnode
3
- Version: 2.0.17
3
+ Version: 2.0.19
4
4
  Summary: Dreadnode SDK
5
5
  Project-URL: Homepage, https://dreadnode.io
6
6
  Project-URL: Documentation, https://docs.dreadnode.io
@@ -21,7 +21,7 @@ Requires-Dist: gepa>=0.1.1
21
21
  Requires-Dist: httpx<1.0.0,>=0.28.0
22
22
  Requires-Dist: jsonpath-ng>=1.7.0
23
23
  Requires-Dist: jsonref>=1.1.0
24
- Requires-Dist: litellm<=1.83.7,>=1.83.7
24
+ Requires-Dist: litellm<=1.83.14,>=1.83.14
25
25
  Requires-Dist: logfire<=3.20.0,>=3.5.3
26
26
  Requires-Dist: loguru>=0.7.3
27
27
  Requires-Dist: markdownify<2.0.0,>=1.1.0
@@ -28,6 +28,8 @@ __all__ = [
28
28
  "FunctionDefinition",
29
29
  "Hook",
30
30
  "JudgeResult",
31
+ "ProcessDecision",
32
+ "ProcessJudge",
31
33
  "Reaction",
32
34
  "Retry",
33
35
  "RetryWithFeedback",
@@ -44,6 +46,7 @@ __all__ = [
44
46
  "exceptions",
45
47
  "hooks",
46
48
  "mcp",
49
+ "process_judge_hook",
47
50
  "reactions",
48
51
  "skills",
49
52
  "stopping",
@@ -63,6 +66,9 @@ _LAZY_NAMES = frozenset(
63
66
  "Agent",
64
67
  "AgentJudge",
65
68
  "JudgeResult",
69
+ "ProcessDecision",
70
+ "ProcessJudge",
71
+ "process_judge_hook",
66
72
  "Trajectory",
67
73
  "Continue",
68
74
  "Fail",
@@ -94,6 +100,9 @@ def _lazy_init() -> None:
94
100
  # construction mirror for trajectory-scoring use cases.
95
101
  _Agent.Judge = _judge.AgentJudge
96
102
 
103
+ _process_judge = importlib.import_module("dreadnode.agents.process_judge")
104
+ _hooks = importlib.import_module("dreadnode.agents.hooks")
105
+
97
106
  g = globals()
98
107
  g["events"] = _events
99
108
  g["reactions"] = _reactions
@@ -101,6 +110,9 @@ def _lazy_init() -> None:
101
110
  g["Agent"] = _Agent
102
111
  g["AgentJudge"] = _judge.AgentJudge
103
112
  g["JudgeResult"] = _judge.JudgeResult
113
+ g["ProcessDecision"] = _process_judge.ProcessDecision
114
+ g["ProcessJudge"] = _process_judge.ProcessJudge
115
+ g["process_judge_hook"] = _hooks.process_judge_hook
104
116
  g["Trajectory"] = _Trajectory
105
117
  g["Continue"] = _reactions.Continue
106
118
  g["Fail"] = _reactions.Fail
@@ -12,10 +12,11 @@ from dataclasses import dataclass
12
12
  from dreadnode.agents.events import (
13
13
  AgentEvent,
14
14
  AgentStep,
15
+ GenerationStart,
15
16
  ToolEnd,
16
17
  ToolStart,
17
18
  )
18
- from dreadnode.agents.reactions import Reaction, Retry
19
+ from dreadnode.agents.reactions import Fail, Finish, Reaction, Retry, RetryWithFeedback
19
20
  from dreadnode.core.hook import Hook, hook
20
21
  from dreadnode.generators.generator import Generator
21
22
  from dreadnode.generators.message import Message, make_compaction_message
@@ -23,6 +24,8 @@ from dreadnode.generators.message import Message, make_compaction_message
23
24
  if t.TYPE_CHECKING:
24
25
  from datetime import datetime
25
26
 
27
+ from dreadnode.agents.process_judge import ProcessJudge
28
+
26
29
 
27
30
  # =============================================================================
28
31
  # Tool Metrics
@@ -410,3 +413,251 @@ def _make_summarize_hook(
410
413
 
411
414
  # Pre-instantiated with defaults -- this is what the wrapper discovers
412
415
  summarize_when_long = _make_summarize_hook()
416
+
417
+
418
+ # =============================================================================
419
+ # Process Judge (guard policy)
420
+ # =============================================================================
421
+
422
+ TranscriptStrategy = t.Literal[
423
+ "rubric_only",
424
+ "intent_only",
425
+ "intent_plus_calls",
426
+ "intent_plus_outputs",
427
+ "full",
428
+ ]
429
+ OnDeny = t.Literal["retry", "finish"]
430
+ OnJudgeError = t.Literal["deny", "allow", "fail"]
431
+
432
+
433
+ def _strip_intent(messages: list[Message], strategy: TranscriptStrategy) -> list[Message]:
434
+ """Slice ``messages`` per ``strategy``.
435
+
436
+ - ``rubric_only``: empty list. Judge sees only the proposed call.
437
+ - ``intent_only``: system + user-authored only. Smallest prompt and
438
+ narrowest attack surface — tool outputs and tool calls never reach
439
+ the judge.
440
+ - ``intent_plus_calls``: above + assistant messages that carry
441
+ ``tool_calls`` (no tool result messages, no text-only assistant
442
+ turns). Lets the judge see the tool-call sequence leading up to
443
+ this call without exposing it to attacker-controllable tool
444
+ output content.
445
+ - ``intent_plus_outputs``: ``intent_only`` + tool-result messages.
446
+ Tool calls themselves are stripped; the judge sees responses
447
+ without knowing which call produced them. Widens the injection
448
+ surface — adversarial tool output can target the judge.
449
+ - ``full``: messages unchanged. Maximum context, maximum surface.
450
+ """
451
+ if strategy == "full":
452
+ return list(messages)
453
+ if strategy == "rubric_only":
454
+ return []
455
+ if strategy == "intent_only":
456
+ return [m for m in messages if m.role in ("system", "user")]
457
+ if strategy == "intent_plus_calls":
458
+ return [
459
+ m
460
+ for m in messages
461
+ if m.role in ("system", "user")
462
+ or (m.role == "assistant" and getattr(m, "tool_calls", None))
463
+ ]
464
+ if strategy == "intent_plus_outputs":
465
+ return [m for m in messages if m.role in ("system", "user", "tool")]
466
+ raise ValueError(f"unknown transcript_strategy: {strategy!r}")
467
+
468
+
469
+ def _trim_intent_to_budget(
470
+ intent: list[Message],
471
+ model: "str | Generator | None",
472
+ ) -> tuple[list[Message], int]:
473
+ """Drop oldest non-protected messages until intent fits the judge's budget.
474
+
475
+ Returns ``(trimmed, dropped_count)``. The system message and the first
476
+ user message (the original task) are always preserved — the rest is
477
+ eligible for eviction, oldest first.
478
+
479
+ ``str(message)`` matches what :func:`ProcessJudge._render_intent` writes
480
+ into the judge prompt, so the char count and the actual rendered prompt
481
+ measure the same string. We allocate ~80 % of the judge model's char
482
+ budget (roughly 4 chars/token of its max input window) so the rubric
483
+ block and the proposed-call block still have headroom.
484
+ """
485
+ budget_tokens = _get_model_context_budget(model)
486
+ char_budget = int(budget_tokens * 4 * 0.8)
487
+
488
+ if not intent:
489
+ return [], 0
490
+
491
+ protected_end = 0
492
+ if intent[0].role == "system":
493
+ protected_end = 1
494
+ for i in range(protected_end, len(intent)):
495
+ if intent[i].role == "user":
496
+ protected_end = i + 1
497
+ break
498
+
499
+ current = sum(len(str(m)) for m in intent)
500
+ if current <= char_budget:
501
+ return list(intent), 0
502
+
503
+ # Walk a cursor forward, subtracting each evicted message's char count
504
+ # from the running total. Single slice at the end — no repeated full-list
505
+ # walks, no in-place mutation.
506
+ drop_from = protected_end
507
+ dropped = 0
508
+ while current > char_budget and drop_from < len(intent):
509
+ current -= len(str(intent[drop_from]))
510
+ drop_from += 1
511
+ dropped += 1
512
+
513
+ return intent[:protected_end] + intent[drop_from:], dropped
514
+
515
+
516
+ def _deny_reaction(reason: str, on_deny: OnDeny) -> Reaction:
517
+ if on_deny == "retry":
518
+ return RetryWithFeedback(feedback=reason)
519
+ return Finish(reason=f"policy denied: {reason}")
520
+
521
+
522
+ def _judge_error_reaction(exc: Exception, on_judge_error: OnJudgeError) -> Reaction | None:
523
+ from loguru import logger
524
+
525
+ if on_judge_error == "deny":
526
+ return Finish(reason=f"process judge unreachable: {exc}")
527
+ if on_judge_error == "allow":
528
+ logger.warning("process judge errored, allowing tool call: {}", exc)
529
+ return None
530
+ return Fail(error=exc)
531
+
532
+
533
+ def process_judge_hook(
534
+ judge: "ProcessJudge",
535
+ *,
536
+ transcript_strategy: TranscriptStrategy = "intent_plus_calls",
537
+ on_deny: OnDeny = "retry",
538
+ on_judge_error: OnJudgeError = "deny",
539
+ always_allow: t.Sequence[str] = (),
540
+ always_deny: t.Sequence[str] = (),
541
+ context_provider: t.Callable[[ToolStart], dict[str, t.Any]] | None = None,
542
+ ) -> Hook:
543
+ """Pre-tool-call gating hook backed by a :class:`ProcessJudge`.
544
+
545
+ Listens to ``GenerationStart`` to snapshot the message state going
546
+ into each generation, then judges every ``ToolStart`` against that
547
+ snapshot. ``always_allow`` / ``always_deny`` short-circuit the judge
548
+ call. ``always_deny`` wins ties. The captured intent is sliced per
549
+ ``transcript_strategy`` and then trimmed to fit the judge model's
550
+ context window (oldest non-protected messages drop first; the system
551
+ message and the original user task are always preserved).
552
+
553
+ Decisions map to reactions:
554
+
555
+ - allow → ``None`` (tool runs).
556
+ - deny + ``on_deny="retry"`` → :class:`RetryWithFeedback`.
557
+ - deny + ``on_deny="finish"`` → :class:`Finish` with ``"policy denied: …"``.
558
+ - judge raises + ``on_judge_error="deny"`` → :class:`Finish`.
559
+ - judge raises + ``on_judge_error="allow"`` → ``None`` plus warn-level log.
560
+ - judge raises + ``on_judge_error="fail"`` → :class:`Fail`.
561
+ """
562
+ import time
563
+
564
+ deny_set = set(always_deny)
565
+ allow_set = set(always_allow) - deny_set
566
+
567
+ _last_messages: list[Message] = []
568
+
569
+ @hook(AgentEvent)
570
+ async def process_judge_hook_inner(event: AgentEvent) -> Reaction | None:
571
+ nonlocal _last_messages
572
+ from dreadnode import log_metric
573
+
574
+ if isinstance(event, GenerationStart):
575
+ _last_messages = list(event.messages)
576
+ return None
577
+
578
+ if not isinstance(event, ToolStart):
579
+ return None
580
+
581
+ tool_name = event.tool_call.name
582
+ start = time.monotonic()
583
+
584
+ if tool_name in deny_set:
585
+ log_metric(
586
+ "process_judge.deny",
587
+ 1,
588
+ attributes={
589
+ "tool_name": tool_name,
590
+ "short_circuit": True,
591
+ "reason": "always_deny",
592
+ },
593
+ )
594
+ return _deny_reaction(f"tool {tool_name!r} is in always_deny list", on_deny)
595
+
596
+ if tool_name in allow_set:
597
+ log_metric(
598
+ "process_judge.allow",
599
+ 1,
600
+ attributes={"tool_name": tool_name, "short_circuit": True},
601
+ )
602
+ return None
603
+
604
+ intent = _strip_intent(_last_messages, transcript_strategy)
605
+ intent, dropped = _trim_intent_to_budget(intent, judge.model)
606
+ if dropped:
607
+ log_metric(
608
+ "process_judge.intent_trimmed",
609
+ 1,
610
+ attributes={
611
+ "tool_name": tool_name,
612
+ "strategy": transcript_strategy,
613
+ "dropped_messages": dropped,
614
+ },
615
+ )
616
+ context = context_provider(event) if context_provider else None
617
+
618
+ try:
619
+ decision = await judge.evaluate(
620
+ intent=intent,
621
+ proposed_call=event.tool_call,
622
+ context=context,
623
+ )
624
+ except Exception as exc:
625
+ latency_ms = int((time.monotonic() - start) * 1000)
626
+ log_metric(
627
+ "process_judge.error",
628
+ 1,
629
+ attributes={
630
+ "tool_name": tool_name,
631
+ "error_type": type(exc).__name__,
632
+ "error_message": str(exc),
633
+ "latency_ms": latency_ms,
634
+ },
635
+ )
636
+ return _judge_error_reaction(exc, on_judge_error)
637
+
638
+ latency_ms = int((time.monotonic() - start) * 1000)
639
+ if decision.allow:
640
+ log_metric(
641
+ "process_judge.allow",
642
+ 1,
643
+ attributes={
644
+ "tool_name": tool_name,
645
+ "short_circuit": False,
646
+ "latency_ms": latency_ms,
647
+ },
648
+ )
649
+ return None
650
+
651
+ log_metric(
652
+ "process_judge.deny",
653
+ 1,
654
+ attributes={
655
+ "tool_name": tool_name,
656
+ "short_circuit": False,
657
+ "reason": decision.reason,
658
+ "latency_ms": latency_ms,
659
+ },
660
+ )
661
+ return _deny_reaction(decision.reason, on_deny)
662
+
663
+ return process_judge_hook_inner
@@ -0,0 +1,212 @@
1
+ """ProcessJudge — LLM-backed gate over (intent, proposed tool call) pairs.
2
+
3
+ The primitive layer of the guard policy. ``ProcessJudge`` knows
4
+ nothing about ``Trajectory``, ``Hook``, or ``SessionPolicy`` — it takes
5
+ pre-shaped inputs (a list of :class:`Message` plus a :class:`ToolCall`)
6
+ and returns a :class:`ProcessDecision`. Hook code is responsible for the
7
+ trajectory-to-intent transformation.
8
+
9
+ Composition: reuses the lower-level :func:`dreadnode.scorers.judge.judge`
10
+ function so XML response parsing and the regex fallback stay in one
11
+ place. The default safety-floor rubric ships at
12
+ ``dreadnode/policies/rubrics/process/default.yaml`` and is layered with
13
+ any user-supplied rubric under a ``## Project-specific scope`` header
14
+ unless ``replace_default_rubric=True``.
15
+ """
16
+
17
+ import typing as t
18
+ from dataclasses import dataclass
19
+ from pathlib import Path
20
+
21
+ from dreadnode.generators.generator import GenerateParams, Generator, get_generator
22
+
23
+ if t.TYPE_CHECKING:
24
+ from dreadnode.agents.tools import ToolCall
25
+ from dreadnode.generators.message import Message
26
+
27
+
28
+ _DEFAULT_RUBRIC_PATH: Path = (
29
+ Path(__file__).parent.parent / "policies" / "rubrics" / "process" / "default.yaml"
30
+ )
31
+
32
+ _USER_RUBRIC_HEADER = "## Project-specific scope"
33
+
34
+
35
+ @dataclass(slots=True)
36
+ class ProcessDecision:
37
+ """Outcome of one :class:`ProcessJudge` invocation.
38
+
39
+ Two-valued by design — the agent will run an allowed call or won't run
40
+ a denied one. A "warn" mode is deliberately absent; the gating layer
41
+ cannot usefully half-allow a tool call.
42
+ """
43
+
44
+ allow: bool
45
+ reason: str
46
+
47
+
48
+ class ProcessJudge:
49
+ """LLM-backed gate over (intent, proposed tool call) pairs.
50
+
51
+ Example::
52
+
53
+ from dreadnode.agents.process_judge import ProcessJudge
54
+
55
+ judge = ProcessJudge(
56
+ model="anthropic/claude-haiku-4-5",
57
+ rubric="In-scope domains: api.example.com",
58
+ )
59
+ decision = await judge.evaluate(
60
+ intent=session_messages,
61
+ proposed_call=tool_call,
62
+ )
63
+ if not decision.allow:
64
+ print("denied:", decision.reason)
65
+ """
66
+
67
+ def __init__(
68
+ self,
69
+ *,
70
+ model: str | Generator,
71
+ rubric: str | Path | None = None,
72
+ replace_default_rubric: bool = False,
73
+ model_params: dict[str, t.Any] | None = None,
74
+ system_prompt: str | None = None,
75
+ ) -> None:
76
+ if rubric is None and replace_default_rubric:
77
+ raise ValueError("replace_default_rubric=True requires a user-supplied rubric")
78
+
79
+ from dreadnode.scorers.judge import _load_rubric_from_yaml
80
+
81
+ default_text, default_system_prompt, _ = _load_rubric_from_yaml(
82
+ _DEFAULT_RUBRIC_PATH, system_prompt=None, name="process_default"
83
+ )
84
+
85
+ if rubric is None:
86
+ final_rubric = default_text
87
+ else:
88
+ user_text = self._resolve_user_rubric(rubric)
89
+ final_rubric = (
90
+ user_text
91
+ if replace_default_rubric
92
+ else f"{default_text}\n\n{_USER_RUBRIC_HEADER}\n{user_text}"
93
+ )
94
+
95
+ self._model = model
96
+ self._rubric = final_rubric
97
+ self._system_prompt = system_prompt or default_system_prompt
98
+ self._model_params = model_params
99
+
100
+ @property
101
+ def model(self) -> str | Generator:
102
+ return self._model
103
+
104
+ @property
105
+ def rubric(self) -> str:
106
+ return self._rubric
107
+
108
+ @property
109
+ def system_prompt(self) -> str | None:
110
+ return self._system_prompt
111
+
112
+ async def evaluate(
113
+ self,
114
+ *,
115
+ intent: "list[Message]",
116
+ proposed_call: "ToolCall",
117
+ context: dict[str, t.Any] | None = None,
118
+ ) -> ProcessDecision:
119
+ """Evaluate a proposed tool call against the rubric.
120
+
121
+ Args:
122
+ intent: Trajectory-stripped messages representing the user's
123
+ intent (typically system + user-authored, optionally tool
124
+ outputs depending on the hook's strategy).
125
+ proposed_call: The tool call about to execute. Wire name and
126
+ arguments are passed verbatim — argument redaction is a
127
+ separate concern.
128
+ context: Optional per-call context (task instruction, scope
129
+ metadata) merged into the rendered intent.
130
+
131
+ Returns:
132
+ A :class:`ProcessDecision` with ``allow`` and a short reason.
133
+ """
134
+ from dreadnode.scorers.judge import JudgeInput, judge
135
+
136
+ intent_text = self._render_intent(intent, context=context)
137
+ proposed_call_text = self._render_proposed_call(proposed_call)
138
+
139
+ generator = self._resolve_generator()
140
+ input_data = JudgeInput(
141
+ input=intent_text,
142
+ output=proposed_call_text,
143
+ rubric=self._rubric,
144
+ )
145
+
146
+ judgement = await judge(generator, input_data, system_prompt=self._system_prompt)
147
+ return ProcessDecision(allow=judgement.passing, reason=judgement.reason)
148
+
149
+ def _resolve_generator(self) -> Generator:
150
+ if isinstance(self._model, Generator):
151
+ return self._model
152
+ if not isinstance(self._model, str):
153
+ raise TypeError("model must be a string identifier or a Generator instance.")
154
+ params: GenerateParams | None
155
+ if self._model_params is None:
156
+ params = None
157
+ elif isinstance(self._model_params, GenerateParams):
158
+ params = self._model_params
159
+ else:
160
+ params = GenerateParams.model_validate(self._model_params)
161
+ return get_generator(self._model, params=params)
162
+
163
+ @staticmethod
164
+ def _resolve_user_rubric(rubric: str | Path) -> str:
165
+ """Resolve a user rubric to its body text.
166
+
167
+ Path or YAML-shaped string → load the YAML and read its ``rubric``
168
+ field. Anything else → treat as a plain string and return as-is.
169
+ """
170
+ from dreadnode.scorers.judge import _is_yaml_rubric, _load_rubric_from_yaml
171
+
172
+ if isinstance(rubric, Path) or _is_yaml_rubric(rubric):
173
+ text, _, _ = _load_rubric_from_yaml(rubric, system_prompt=None, name="user")
174
+ return text
175
+ return rubric
176
+
177
+ @staticmethod
178
+ def _render_intent(
179
+ intent: "list[Message]",
180
+ *,
181
+ context: dict[str, t.Any] | None = None,
182
+ ) -> str:
183
+ """Render intent messages as a transcript the judge can consume.
184
+
185
+ Delegates per-message formatting to ``Message.__str__`` so assistant
186
+ ``tool_calls`` and tool-result ``tool_call_id`` headers actually
187
+ appear in the rendered output — without this, ``intent_plus_calls``
188
+ and ``full`` would silently drop the tool-call sequence the judge
189
+ is supposed to be reasoning about.
190
+ """
191
+ lines: list[str] = []
192
+ if context:
193
+ lines.append("# Task context")
194
+ for key, value in context.items():
195
+ lines.append(f"- {key}: {value}")
196
+ lines.append("")
197
+ if intent:
198
+ lines.append("# Intent transcript")
199
+ for msg in intent:
200
+ lines.append(str(msg))
201
+ return "\n".join(lines)
202
+
203
+ @staticmethod
204
+ def _render_proposed_call(proposed_call: "ToolCall") -> str:
205
+ """Render the proposed tool call in a structured XML block."""
206
+ return (
207
+ f"<tool>{proposed_call.name}</tool>\n"
208
+ f"<arguments>{proposed_call.function.arguments}</arguments>"
209
+ )
210
+
211
+
212
+ __all__ = ["ProcessDecision", "ProcessJudge"]
@@ -56,6 +56,26 @@ class AuthenticationError(RuntimeError):
56
56
  """Raised when the platform returns HTTP 401."""
57
57
 
58
58
 
59
+ class NotFoundError(RuntimeError):
60
+ """Raised when the platform returns HTTP 404 for a resource lookup.
61
+
62
+ Subclass of :class:`RuntimeError` so existing ``except RuntimeError``
63
+ handlers keep working; callers that want 404-specific recovery (e.g.
64
+ idempotent deletes that tolerate already-gone resources) can catch
65
+ this directly instead of pattern-matching on error message strings.
66
+ """
67
+
68
+
69
+ class ConflictError(RuntimeError):
70
+ """Raised when the platform returns HTTP 409 for a state conflict.
71
+
72
+ Subclass of :class:`RuntimeError` so existing ``except RuntimeError``
73
+ handlers keep working; callers that want conflict-specific UX (e.g.
74
+ refusing to delete a session linked to an evaluation) can catch this
75
+ directly instead of pattern-matching on error message strings.
76
+ """
77
+
78
+
59
79
  class PlatformBackendUnavailableError(RuntimeError):
60
80
  """Raised when the platform endpoint is transiently unavailable.
61
81
 
@@ -176,6 +196,10 @@ class ApiClient:
176
196
  response = self._request(method, path, params, json_data, data, headers)
177
197
  if response.status_code == 401:
178
198
  raise AuthenticationError(self._get_error_message(response))
199
+ if response.status_code == 404:
200
+ raise NotFoundError(self._get_error_message(response))
201
+ if response.status_code == 409:
202
+ raise ConflictError(self._get_error_message(response))
179
203
  if response.status_code == 429:
180
204
  error_message = self._get_error_message(response)
181
205
  detail = error_message.split(": ", 1)[1] if ": " in error_message else error_message
@@ -2243,27 +2267,18 @@ class ApiClient:
2243
2267
  org: str,
2244
2268
  workspace: str,
2245
2269
  session_id: str,
2246
- ) -> bool:
2270
+ ) -> None:
2247
2271
  """DELETE /org/{org}/ws/{workspace}/sessions/{id}.
2248
2272
 
2249
- Returns ``True`` when the platform deleted the row, ``False`` when
2250
- the session was already absent (404). Other failures raise — a
2251
- local-only session that was never registered with the platform
2252
- still 404s here, so the caller can safely treat that as success.
2273
+ Raises :class:`NotFoundError` if the session does not exist. Callers
2274
+ that want to tolerate already-gone sessions (e.g. delete propagation
2275
+ for sessions that were never registered with the platform) should
2276
+ catch :class:`NotFoundError` explicitly.
2253
2277
  """
2254
- response = self._request(
2278
+ self.request(
2255
2279
  "DELETE",
2256
2280
  f"/org/{org}/ws/{workspace}/sessions/{session_id}",
2257
2281
  )
2258
- if response.status_code == 404:
2259
- return False
2260
- if response.status_code == 401:
2261
- raise AuthenticationError(self._get_error_message(response))
2262
- try:
2263
- response.raise_for_status()
2264
- except httpx.HTTPStatusError as e:
2265
- raise RuntimeError(self._get_error_message(response)) from e
2266
- return True
2267
2282
 
2268
2283
  def unarchive_session(
2269
2284
  self,
@@ -2396,6 +2411,60 @@ class ApiClient:
2396
2411
  )
2397
2412
  return t.cast("dict[str, t.Any]", response.json())
2398
2413
 
2414
+ def get_session_trajectory(
2415
+ self,
2416
+ org: str,
2417
+ workspace: str,
2418
+ session_id: str,
2419
+ *,
2420
+ format: t.Literal["atif", "openai", "native"] = "atif",
2421
+ include_compacted: bool = False,
2422
+ ) -> t.Any:
2423
+ """GET /org/{org}/ws/{workspace}/sessions/{id}/trajectory.
2424
+
2425
+ Returns the session's trajectory in the requested format. ``atif``
2426
+ emits an ATIF v1.7 dict; ``openai`` emits a Chat Completions
2427
+ ``messages`` list; ``native`` emits a Dreadnode bundle of session
2428
+ metadata, transcript messages, and ClickHouse events.
2429
+ ``include_compacted=True`` requests full history.
2430
+ """
2431
+ params: dict[str, t.Any] = {
2432
+ "format": format,
2433
+ "include_compacted": include_compacted,
2434
+ }
2435
+ response = self.request(
2436
+ "GET",
2437
+ f"/org/{org}/ws/{workspace}/sessions/{session_id}/trajectory",
2438
+ params=params,
2439
+ )
2440
+ return response.json()
2441
+
2442
+ def get_evaluation_item_trajectory(
2443
+ self,
2444
+ org: str,
2445
+ workspace: str,
2446
+ evaluation_id: str,
2447
+ item_id: str,
2448
+ *,
2449
+ format: t.Literal["atif", "openai"] = "atif",
2450
+ include_compacted: bool = False,
2451
+ ) -> t.Any:
2452
+ """GET /org/{org}/ws/{workspace}/evaluation/{id}/items/{item_id}/trajectory.
2453
+
2454
+ Convenience alias that resolves the linked session and delegates
2455
+ (SES-TRAJ-031). 404 if the eval item has no linked session.
2456
+ """
2457
+ params: dict[str, t.Any] = {
2458
+ "format": format,
2459
+ "include_compacted": include_compacted,
2460
+ }
2461
+ response = self.request(
2462
+ "GET",
2463
+ f"/org/{org}/ws/{workspace}/evaluation/{evaluation_id}/items/{item_id}/trajectory",
2464
+ params=params,
2465
+ )
2466
+ return response.json()
2467
+
2399
2468
  # ------------------------------------------------------------------
2400
2469
  # Session transcripts (message-level persistence)
2401
2470
  # ------------------------------------------------------------------
@@ -155,6 +155,8 @@ class User(BaseModel):
155
155
  """User's full display name."""
156
156
  onboarding_complete: bool = False
157
157
  """Whether the user has completed onboarding."""
158
+ email_opt_in: bool = False
159
+ """Whether the user has opted in to product/marketing email."""
158
160
  is_platform_admin: bool = False
159
161
  """Whether the user has platform admin privileges."""
160
162
  features: list[str] | None = Field(default_factory=list)