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.
- {dreadnode-2.0.22 → dreadnode-2.0.24}/PKG-INFO +2 -1
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/assessment.py +45 -5
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/api/client.py +21 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/airt.py +130 -11
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/main.py +9 -1
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/client/runtime_client.py +36 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/main.py +7 -2
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/app.py +179 -9
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/app.py +177 -3
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/command_dispatcher.py +3 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/commands.py +1 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/dreadnode.tcss +3 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/composer.py +2 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/help_panel.py +5 -2
- dreadnode-2.0.24/dreadnode/app/tui/widgets/rewind_picker.py +203 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/tool_progress.py +1 -1
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/dependencies-and-checks.md +19 -7
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/sdk/capabilities.md +38 -0
- dreadnode-2.0.24/dreadnode/capabilities/install.py +226 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/capabilities/loader.py +46 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/pyproject.toml +2 -1
- {dreadnode-2.0.22 → dreadnode-2.0.24}/.gitignore +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/LICENSE +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/README.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/__main__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/agent.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/events.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/exceptions.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/format.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/hooks.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/judge.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/mcp/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/mcp/auth.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/mcp/client.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/mcp/config.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/mcp/server.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/process_judge.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/reactions.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/skills.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/stopping.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/subagent.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/tool_resolution.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/tools.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/agents/trajectory.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/adversarial_reasoning.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/advpromptier.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/alignment_faking.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/analogy_escalation.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/analytics/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/analytics/aggregator.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/analytics/classifier.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/analytics/compliance.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/analytics/engine.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/analytics/recommendations.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/analytics/types.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/aprt_progressive.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/attention_shifting.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/autodan_turbo.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/autoredteamer.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/beast.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/compliance/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/compliance/atlas.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/compliance/nist.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/compliance/owasp.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/compliance/owasp_agentic.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/compliance/saif.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/constants.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/cot_jailbreak.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/crescendo.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/assets/audio/adversarial_query.mp3 +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/assets/image/bomb.jpg +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/assets/image/meth.png +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/prompts/adversarial_benchmark_subset.csv +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/prompts/ai_safety.csv +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/rubrics/data_exfiltration.yaml +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/rubrics/goal_hijacking.yaml +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/rubrics/memory_poisoning.yaml +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/rubrics/privilege_escalation.yaml +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/rubrics/rce.yaml +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/rubrics/scope_creep.yaml +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/rubrics/tool_chaining.yaml +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/rubrics/tool_selection_safety.yaml +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/rubrics/unbounded_agency.yaml +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/rubrics/web_chatbot_security.yaml +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/templates/crescendo/variant_1.yaml +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/templates/crescendo/variant_2.yaml +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/templates/crescendo/variant_3.yaml +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/templates/crescendo/variant_4.yaml +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/data/templates/crescendo/variant_5.yaml +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/deep_inception.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/drattack.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/echo_chamber.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/events.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/genetic_persona.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/goat.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/goat_v2.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/gptfuzzer.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/humor_bypass.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/image.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/j2_meta.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/jbdistill.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/jbfuzz.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/lrm_autonomous.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/mapf.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/multimodal.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/nexus.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/pair.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/persona_hijack.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/prompt.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/quantization_safety.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/rainbow.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/refusal_aware.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/renellm.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/reporting/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/reporting/json_report.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/reporting/llm_summary.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/reporting/markdown.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/reward_hacking.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/salami_slicing.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/self_persuasion.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/siren.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/tap.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/templatefuzz.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/tmap_trajectory.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/trojail.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/airt/watermark_removal.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/api/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/api/models.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/args.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/capability.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/dataset.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/environment.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/evaluation.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/inference_model.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/model.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/optimize.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/runtime.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/sandbox.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/secret.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/session.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/shared.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/task.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/templates/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/templates/init/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/templates/init/challenge/Dockerfile +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/templates/init/docker-compose.yaml +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/templates/init/provision.sh +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/templates/init/solution.sh +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/templates/init/task-remote.yaml.tmpl +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/templates/init/task.yaml.tmpl +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/templates/init/teardown.sh +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/templates/init/verify.sh +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/train.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/cli/worlds.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/client/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/client/interactive.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/client/managed_client.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/client/models.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/client/transports.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/config.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/env.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/model_catalog.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/paths.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/print_mode.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/auth.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/capability_manager.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/model_resolution.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/prompt.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/prompt_registry.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/runtime_events.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/session_hydrator.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/session_persistence.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/turn_coordinator.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/utils.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/websocket.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/server/worker_manager.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/auth_flow.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/capabilities_manager.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/connection.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/error_handler.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/model_manager.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/model_variants.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/profile_manager.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/runtime_cache.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screen_router.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/auth.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/base.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/capabilities.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/capability_docs.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/connection_error.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/console.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/environments.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/evaluations.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/model_picker.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/models.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/raw_spans.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/runtimes.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/sandboxes.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/secrets.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/services.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/sessions.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/theme_showcase.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/traces.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/screens/workspaces.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/sessions_manager.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/spans_reader.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/status_messages.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/theme.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/tool_format.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/turn_coordinator.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/turn_lifecycle.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/turn_reducer.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/turn_state_phase.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/update_check.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/agent_dialog.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/agent_suggester.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/confirm_modal.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/context_bar.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/conversation.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/flash.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/header_bar.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/human_prompt.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/mention_overlay.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/message_queue.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/new_messages_pill.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/overlay_mixin.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/permission_prompt.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/profile_dialog.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/prompt_info.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/session_sidebar.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/skills_dialog.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/slash_overlay.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/status_bar.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/throbber.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/tool.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/tools_dialog.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/welcome.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/widgets/whoami.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/app/tui/wire_events.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/MAINTAINING.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/agents/dreadnode.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/capability.yaml +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/SKILL.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/capability-improvement.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/promoting-capabilities.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/INDEX.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/agents.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/env-vars.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/events.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/flags.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/hooks.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/installing.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/manifest.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/mcp-servers.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/overview.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/policies.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/publishing.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/quickstart.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/skills.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/tools.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/workers-reference.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/workers.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/writing-skills.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/guides/capability-optimization-loop.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/sdk/agents.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/tui/default-tools.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/runtime-default-capability.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/SKILL.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/INDEX.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/airt.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/capability.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/dataset.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/env.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/evaluation.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/inference-model.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/main.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/model.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/optimize.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/overview.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/runtime.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/sandbox.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/secret.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/task.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/train.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/worlds.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/getting-started/authentication.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/SKILL.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/INDEX.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/capabilities/installing.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/capabilities/overview.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/getting-started/authentication.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/getting-started/overview.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/getting-started/quickstart.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/chat-models.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/credits.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/organizations.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/overview.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/projects.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/secrets.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/settings.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/users.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/workspaces.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/configuration.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/managing.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/manifest-reference.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/overview.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/quickstart.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/serve.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/sandboxes/environment-lifecycle.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/sandboxes/inspecting.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/sandboxes/overview.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/getting-started/SKILL.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/dreadnode/skills/research-capabilities/SKILL.md +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/self-improvement/.gitignore +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/self-improvement/capability.yaml +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/self-improvement/hooks/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/self-improvement/hooks/observer.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/classifier.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/reflector_goal.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/skill_io.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/self-improvement/skills-promoted/.gitkeep +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/self-improvement/skills-proposed/.gitkeep +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/self-improvement/tools/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/self-improvement/tools/reflector.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/builtin_capabilities/self-improvement/tools/skill_stats.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/capabilities/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/capabilities/capability.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/capabilities/flags.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/capabilities/sync.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/capabilities/tool_rules.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/capabilities/types.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/capabilities/worker.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/capabilities/worker_runner.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/conditions.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/discovery.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/environment.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/exceptions.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/execution.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/hook.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/judge.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/load.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/log.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/meta/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/meta/config.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/meta/context.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/meta/hydrate.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/meta/introspect.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/metric.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/object.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/scorer.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/serialization.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/stopping.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/task.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/templating.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/transforms.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/types/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/types/audio.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/types/base.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/types/common.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/types/image.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/types/object_3d.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/types/table.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/types/text.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/types/video.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/core/util.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/datasets/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/datasets/dataset.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/datasets/hf.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/datasets/local.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/evaluations/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/evaluations/console.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/evaluations/evaluation.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/evaluations/events.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/evaluations/format.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/evaluations/result.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/evaluations/sample.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/caching.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/chat.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/data.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/exceptions.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/generator/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/generator/base.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/generator/http.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/generator/litellm_.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/generator/transformers_.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/generator/vllm_.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/message.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/models.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/parsing.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/tokenizer/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/tokenizer/base.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/tokenizer/transformers_.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/generators/utils.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/models/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/models/hf.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/models/local.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/models/model.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/adapters/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/adapters/_env_eval.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/adapters/agent.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/adapters/env.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/adapters/runtime.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/adapters/stack.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/api.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/backends/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/backends/base.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/backends/gepa.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/collectors.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/config.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/console.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/events.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/format.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/jobs.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/result.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/sampler.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/sampling.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/search.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/stopping.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/study.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/optimization/trial.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/packaging/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/packaging/loader.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/packaging/manifest.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/packaging/oci.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/packaging/package.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/packaging/task_validation.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/policies/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/policies/guard.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/policies/rubrics/process/default.yaml +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/py.typed +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/samplers/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/samplers/boundary.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/samplers/fuzzing.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/samplers/graph.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/samplers/grid.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/samplers/image.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/samplers/mapelites.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/samplers/optuna.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/samplers/random.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/samplers/registry.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/samplers/strategy.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/advanced_jailbreak_detection.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/agent_security.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/agentic.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/agentic_workflow.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/attack_outcome.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/classification.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/consistency.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/contains.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/cosine_sim.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/credentials.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/crucible.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/documentation_security.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/exfiltration_detection.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/format.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/harm.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/ide_security.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/image.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/json.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/judge.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/judge_ensemble.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/length.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/lexical.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/mcp_security.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/memorization.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/multi_agent_security.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/pii.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/prompt_leak.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/readability.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/reasoning_security.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/sentiment.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/similarity.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/structural_detection.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/scorers/supply_chain_detection.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/storage/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/storage/providers.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/storage/session_store.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/storage/storage.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/_ripgrep.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/apply_patch.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/dreadnode_cli.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/editing.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/execute.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/fetch.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/glob.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/grep.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/interaction.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/ls.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/memory.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/read.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/report.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/task.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/think.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/todo.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/trajectory_search.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/web_extract.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/web_search.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tools/write.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tracing/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tracing/constants.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tracing/convert.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tracing/exporter.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tracing/exporters.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tracing/span.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tracing/spans.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/tracing/trace_converter.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/_progress.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/base.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/dpo.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/env_rollouts.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/etl/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/etl/_common.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/etl/rl.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/etl/sft.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/etl/worlds.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/events.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/grpo.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/jobs.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/models.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ppo.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/prime.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/async_trainer.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/config.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/coordinator.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/distributed.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/dpo.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/experience.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/fsdp2_learner.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/inference.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/learner.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/multi_turn.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/ppo.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/reward_model.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/rollout_env.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/rollout_worker.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/sft.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/ray/trainer.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/recipes.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/rewards/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/rewards/aggregator.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/rewards/functions.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/rewards/scorer_bridge.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/rewards/shaping.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/rewards/types.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/rollouts/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/rollouts/adapters.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/rollouts/agent_rollout.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/rollouts/orchestrator.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/rollouts/types.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/rollouts/worlds.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/serving/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/serving/vllm_client.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/sft.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/tinker/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/tinker/config.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/tinker/data.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/tinker/renderer.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/tinker/rl.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/tinker/trainer.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/tinker_sft.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/training/utils.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/__init__.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/advanced_jailbreak.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/adversarial_suffix.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/agent_skill.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/agentic_workflow.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/audio.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/backdoor_finetune.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/browser_agent_attacks.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/cipher.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/competitive_parity.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/constitutional.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/document.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/documentation_poison.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/encoding.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/exfiltration.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/flip_attack.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/guardrail_bypass.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/ide_injection.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/image.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/injection.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/json_tools.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/language.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/logic_bomb.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/mcp_attacks.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/multi_agent_attacks.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/multimodal_attacks.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/persuasion.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/perturbation.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/pii_extraction.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/pythonic_tools.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/rag_poisoning.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/reasoning_attacks.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/refine.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/response_steering.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/structural_exploits.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/stylistic.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/substitution.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/supply_chain.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/swap.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/system_prompt_extraction.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/text.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/video.py +0 -0
- {dreadnode-2.0.22 → dreadnode-2.0.24}/dreadnode/transforms/xml_tools.py +0 -0
- {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.
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
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=
|
|
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=
|
|
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=
|
|
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
|
-
|
|
456
|
-
|
|
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
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
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.
|
|
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(),
|