dreadnode 2.0.31__tar.gz → 2.0.32__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.31 → dreadnode-2.0.32}/PKG-INFO +5 -3
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/agents/agent.py +12 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/agents/subagent.py +48 -15
- dreadnode-2.0.32/dreadnode/airt/message_parts.py +263 -0
- dreadnode-2.0.32/dreadnode/airt/multimodal.py +370 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/api/client.py +237 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/api/models.py +44 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/capability.py +20 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/main.py +6 -5
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/shared.py +11 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/task.py +21 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/client/managed_client.py +2 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/client/models.py +2 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/client/runtime_client.py +100 -2
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/server/app.py +211 -17
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/server/worker_manager.py +16 -2
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/app.py +21 -8
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/model_manager.py +77 -3
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/screens/capabilities.py +43 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/screens/environments.py +31 -1
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/screens/models.py +5 -21
- dreadnode-2.0.32/dreadnode/app/tui/screens/readme.py +101 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/update_check.py +54 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/sdk/agents.md +3 -4
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/sdk/capabilities.md +23 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/capability.md +1 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/task.md +1 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/capabilities/worker_runner.py +32 -4
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/types/video.py +29 -5
- dreadnode-2.0.32/dreadnode/items/__init__.py +15 -0
- dreadnode-2.0.32/dreadnode/items/config.py +150 -0
- dreadnode-2.0.32/dreadnode/items/models.py +80 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/packaging/manifest.py +7 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/packaging/oci.py +57 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tools/__init__.py +12 -0
- dreadnode-2.0.32/dreadnode/tools/report_items.py +662 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tracing/constants.py +6 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tracing/span.py +22 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/pyproject.toml +8 -6
- dreadnode-2.0.31/dreadnode/airt/multimodal.py +0 -210
- {dreadnode-2.0.31 → dreadnode-2.0.32}/.gitignore +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/LICENSE +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/README.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/__main__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/agents/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/agents/engines/AGENTS.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/agents/engines/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/agents/engines/base.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/agents/engines/claude_code.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/agents/engines/native.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/agents/events.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/agents/exceptions.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/agents/format.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/agents/hooks.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/agents/judge.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/agents/mcp/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/agents/mcp/auth.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/agents/mcp/client.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/agents/mcp/config.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/agents/mcp/server.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/agents/process_judge.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/agents/reactions.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/agents/skills.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/agents/stopping.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/agents/tool_resolution.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/agents/tools.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/agents/trajectory.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/adversarial_reasoning.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/advpromptier.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/alignment_faking.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/analogy_escalation.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/analytics/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/analytics/aggregator.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/analytics/classifier.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/analytics/compliance.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/analytics/engine.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/analytics/recommendations.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/analytics/types.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/aprt_progressive.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/assessment.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/attention_shifting.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/autodan_turbo.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/autoredteamer.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/beast.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/compliance/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/compliance/atlas.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/compliance/nist.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/compliance/owasp.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/compliance/owasp_agentic.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/compliance/saif.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/constants.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/cot_jailbreak.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/crescendo.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/data/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/data/assets/audio/adversarial_query.mp3 +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/data/assets/image/bomb.jpg +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/data/assets/image/meth.png +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/data/prompts/adversarial_benchmark_subset.csv +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/data/prompts/ai_safety.csv +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/data/rubrics/data_exfiltration.yaml +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/data/rubrics/goal_hijacking.yaml +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/data/rubrics/idor.yaml +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/data/rubrics/memory_poisoning.yaml +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/data/rubrics/privilege_escalation.yaml +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/data/rubrics/rce.yaml +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/data/rubrics/scope_creep.yaml +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/data/rubrics/tool_chaining.yaml +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/data/rubrics/tool_selection_safety.yaml +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/data/rubrics/unbounded_agency.yaml +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/data/rubrics/web_chatbot_security.yaml +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/data/templates/crescendo/variant_1.yaml +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/data/templates/crescendo/variant_2.yaml +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/data/templates/crescendo/variant_3.yaml +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/data/templates/crescendo/variant_4.yaml +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/data/templates/crescendo/variant_5.yaml +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/deep_inception.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/drattack.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/echo_chamber.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/events.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/genetic_persona.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/goat.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/goat_v2.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/gptfuzzer.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/humor_bypass.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/image.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/j2_meta.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/jbdistill.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/jbfuzz.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/lrm_autonomous.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/mapf.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/nexus.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/pair.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/persona_hijack.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/prompt.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/quantization_safety.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/rainbow.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/refusal_aware.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/renellm.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/reporting/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/reporting/json_report.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/reporting/llm_summary.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/reporting/markdown.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/reward_hacking.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/salami_slicing.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/self_persuasion.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/siren.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/tap.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/templatefuzz.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/tmap_trajectory.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/trojail.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/airt/watermark_removal.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/api/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/airt.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/args.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/dataset.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/environment.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/evaluation.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/inference_model.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/judge.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/model.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/optimize.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/runtime.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/sandbox.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/secret.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/session.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/task_set.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/templates/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/templates/init/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/templates/init/challenge/Dockerfile +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/templates/init/docker-compose.yaml +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/templates/init/provision.sh +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/templates/init/solution.sh +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/templates/init/task-remote.yaml.tmpl +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/templates/init/task.yaml.tmpl +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/templates/init/teardown.sh +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/templates/init/verify.sh +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/train.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/cli/worlds.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/client/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/client/interactive.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/client/transports.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/config.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/env.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/main.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/model_catalog.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/paths.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/print_mode.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/server/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/server/auth.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/server/capability_manager.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/server/model_resolution.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/server/prompt.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/server/prompt_registry.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/server/runtime_events.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/server/session_hydrator.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/server/session_persistence.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/server/turn_coordinator.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/server/utils.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/server/websocket.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/server/ws_auth.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/auth_flow.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/capabilities_manager.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/command_dispatcher.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/commands.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/connection.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/dreadnode.tcss +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/error_handler.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/model_variants.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/profile_manager.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/runtime_cache.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/screen_router.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/screens/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/screens/auth.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/screens/base.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/screens/capability_docs.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/screens/connection_error.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/screens/console.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/screens/evaluations.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/screens/raw_spans.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/screens/runtimes.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/screens/sandboxes.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/screens/secrets.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/screens/services.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/screens/sessions.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/screens/theme_showcase.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/screens/traces.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/screens/workspaces.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/sessions_manager.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/spans_reader.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/status_messages.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/theme.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/tool_format.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/turn_coordinator.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/turn_lifecycle.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/turn_reducer.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/turn_state_phase.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/agent_dialog.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/agent_suggester.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/composer.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/confirm_modal.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/context_bar.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/conversation.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/flash.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/header_bar.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/help_panel.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/human_prompt.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/mention_overlay.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/message_queue.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/new_messages_pill.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/overlay_mixin.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/permission_prompt.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/profile_dialog.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/prompt_info.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/rewind_picker.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/session_sidebar.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/skills_dialog.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/slash_overlay.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/status_bar.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/throbber.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/tool.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/tool_progress.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/tools_dialog.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/welcome.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/widgets/whoami.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/app/tui/wire_events.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/MAINTAINING.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/agents/dreadnode.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/capability.yaml +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/SKILL.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/capability-improvement.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/methodology-grounding.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/prior-art-audit.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/promoting-capabilities.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/quality-bar.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/INDEX.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/agents.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/custom-engines.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/dependencies-and-checks.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/engines.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/env-vars.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/events.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/flags.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/hooks.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/installing.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/manifest.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/mcp-servers.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/overview.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/policies.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/publishing.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/quickstart.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/skills.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/tools.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/workers-reference.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/workers.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/writing-skills.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/tui/default-tools.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references-and-depth.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/runtime-default-capability.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/SKILL.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/INDEX.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/airt.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/dataset.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/env.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/evaluation.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/inference-model.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/main.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/model.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/optimize.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/overview.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/runtime.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/sandbox.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/secret.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/task-set.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/train.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/worlds.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/getting-started/authentication.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/SKILL.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/INDEX.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/capabilities/installing.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/capabilities/overview.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/getting-started/authentication.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/getting-started/overview.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/getting-started/quickstart.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/chat-models.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/credits.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/organizations.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/overview.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/projects.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/secrets.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/settings.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/users.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/workspaces.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/configuration.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/managing.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/manifest-reference.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/overview.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/quickstart.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/serve.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/sandboxes/environment-lifecycle.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/sandboxes/inspecting.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/sandboxes/overview.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/sandboxes/runtime-limits.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/getting-started/SKILL.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/dreadnode/skills/research-capabilities/SKILL.md +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/self-improvement/.gitignore +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/self-improvement/capability.yaml +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/self-improvement/hooks/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/self-improvement/hooks/observer.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/classifier.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/reflector_goal.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/skill_io.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/self-improvement/skills-promoted/.gitkeep +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/self-improvement/skills-proposed/.gitkeep +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/self-improvement/tools/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/self-improvement/tools/reflector.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/builtin_capabilities/self-improvement/tools/skill_stats.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/capabilities/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/capabilities/capability.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/capabilities/flags.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/capabilities/install.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/capabilities/loader.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/capabilities/sync.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/capabilities/tool_rules.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/capabilities/types.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/capabilities/worker.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/conditions.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/discovery.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/environment.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/exceptions.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/execution.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/hook.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/judge.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/load.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/log.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/meta/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/meta/config.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/meta/context.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/meta/hydrate.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/meta/introspect.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/metric.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/object.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/scorer.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/serialization.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/stopping.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/task.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/templating.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/transforms.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/types/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/types/audio.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/types/base.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/types/common.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/types/image.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/types/object_3d.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/types/table.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/types/text.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/core/util.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/datasets/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/datasets/dataset.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/datasets/hf.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/datasets/local.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/evaluations/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/evaluations/console.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/evaluations/evaluation.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/evaluations/events.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/evaluations/format.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/evaluations/result.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/evaluations/sample.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/generators/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/generators/caching.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/generators/chat.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/generators/data.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/generators/exceptions.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/generators/generator/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/generators/generator/base.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/generators/generator/http.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/generators/generator/litellm_.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/generators/generator/transformers_.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/generators/generator/vllm_.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/generators/message.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/generators/models.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/generators/parsing.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/generators/proxy.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/generators/tokenizer/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/generators/tokenizer/base.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/generators/tokenizer/transformers_.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/generators/utils.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/judges/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/judges/outcome.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/judges/trajectory.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/judges/trajectory_tools.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/models/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/models/hf.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/models/local.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/models/model.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/optimization/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/optimization/adapters/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/optimization/adapters/_env_eval.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/optimization/adapters/agent.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/optimization/adapters/env.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/optimization/adapters/runtime.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/optimization/adapters/stack.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/optimization/api.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/optimization/backends/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/optimization/backends/base.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/optimization/backends/gepa.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/optimization/collectors.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/optimization/config.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/optimization/console.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/optimization/events.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/optimization/format.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/optimization/jobs.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/optimization/result.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/optimization/sampler.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/optimization/sampling.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/optimization/search.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/optimization/stopping.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/optimization/study.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/optimization/trial.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/packaging/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/packaging/loader.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/packaging/package.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/packaging/task_validation.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/policies/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/policies/guard.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/policies/reconciliation.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/policies/rubrics/process/default.yaml +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/py.typed +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/samplers/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/samplers/boundary.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/samplers/fuzzing.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/samplers/graph.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/samplers/grid.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/samplers/image.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/samplers/mapelites.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/samplers/optuna.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/samplers/random.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/samplers/registry.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/samplers/strategy.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/advanced_jailbreak_detection.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/agent_security.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/agentic.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/agentic_workflow.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/attack_outcome.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/classification.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/consistency.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/contains.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/cosine_sim.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/credentials.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/crucible.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/documentation_security.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/exfiltration_detection.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/format.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/harm.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/ide_security.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/image.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/json.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/judge.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/judge_ensemble.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/length.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/lexical.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/mcp_security.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/memorization.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/multi_agent_security.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/pii.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/prompt_leak.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/readability.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/reasoning_security.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/sentiment.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/similarity.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/structural_detection.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/scorers/supply_chain_detection.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/storage/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/storage/providers.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/storage/session_store.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/storage/storage.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tools/_ripgrep.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tools/apply_patch.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tools/dreadnode_cli.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tools/editing.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tools/execute.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tools/fetch.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tools/glob.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tools/grep.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tools/interaction.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tools/ls.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tools/memory.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tools/project_memory.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tools/read.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tools/report.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tools/task.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tools/think.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tools/todo.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tools/trajectory_search.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tools/web_extract.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tools/web_search.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tools/write.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tracing/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tracing/convert.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tracing/exporter.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tracing/exporters.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tracing/spans.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/tracing/trace_converter.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/_progress.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/base.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/dpo.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/env_rollouts.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/etl/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/etl/_common.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/etl/rl.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/etl/sft.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/etl/worlds.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/events.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/grpo.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/jobs.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/models.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/ppo.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/prime.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/ray/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/ray/async_trainer.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/ray/config.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/ray/coordinator.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/ray/distributed.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/ray/dpo.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/ray/experience.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/ray/fsdp2_learner.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/ray/inference.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/ray/learner.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/ray/multi_turn.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/ray/ppo.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/ray/reward_model.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/ray/rollout_env.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/ray/rollout_worker.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/ray/sft.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/ray/trainer.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/recipes.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/rewards/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/rewards/aggregator.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/rewards/functions.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/rewards/scorer_bridge.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/rewards/shaping.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/rewards/types.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/rollouts/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/rollouts/adapters.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/rollouts/agent_rollout.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/rollouts/orchestrator.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/rollouts/types.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/rollouts/worlds.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/serving/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/serving/vllm_client.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/sft.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/tinker/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/tinker/config.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/tinker/data.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/tinker/renderer.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/tinker/rl.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/tinker/trainer.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/tinker_sft.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/training/utils.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/__init__.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/advanced_jailbreak.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/adversarial_suffix.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/agent_skill.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/agentic_workflow.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/audio.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/backdoor_finetune.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/browser_agent_attacks.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/cipher.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/competitive_parity.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/constitutional.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/document.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/documentation_poison.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/encoding.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/exfiltration.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/flip_attack.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/guardrail_bypass.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/ide_injection.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/image.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/injection.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/json_tools.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/language.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/logic_bomb.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/mcp_attacks.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/multi_agent_attacks.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/multimodal_attacks.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/persuasion.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/perturbation.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/pii_extraction.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/pythonic_tools.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/rag_poisoning.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/reasoning_attacks.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/refine.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/response_steering.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/structural_exploits.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/stylistic.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/substitution.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/supply_chain.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/swap.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/system_prompt_extraction.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/text.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/video.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/dreadnode/transforms/xml_tools.py +0 -0
- {dreadnode-2.0.31 → dreadnode-2.0.32}/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.32
|
|
4
4
|
Summary: Dreadnode SDK
|
|
5
5
|
Project-URL: Homepage, https://dreadnode.io
|
|
6
6
|
Project-URL: Documentation, https://docs.dreadnode.io
|
|
@@ -27,14 +27,13 @@ Requires-Dist: loguru>=0.7.3
|
|
|
27
27
|
Requires-Dist: markdown-it-py[linkify]>=2.1.0
|
|
28
28
|
Requires-Dist: markdownify<2.0.0,>=1.1.0
|
|
29
29
|
Requires-Dist: mcp<2.0.0,>=1.25.0
|
|
30
|
-
Requires-Dist: moviepy<3.0.0,>=2.1.2
|
|
31
30
|
Requires-Dist: networkx>=3.6.1
|
|
32
31
|
Requires-Dist: numpy<=2.3.5,>=2.3.0
|
|
33
32
|
Requires-Dist: optuna<5.0.0,>=4.5.0
|
|
34
33
|
Requires-Dist: orjson>=3.11.5
|
|
35
34
|
Requires-Dist: packaging>=24.0
|
|
36
35
|
Requires-Dist: pandas<3.0.0,>=2.2.3
|
|
37
|
-
Requires-Dist: pillow<
|
|
36
|
+
Requires-Dist: pillow<13.0.0,>=11.0.0
|
|
38
37
|
Requires-Dist: prompt-toolkit<4.0.0,>=3.0.52
|
|
39
38
|
Requires-Dist: pyarrow>=4.0.0
|
|
40
39
|
Requires-Dist: pydantic-xml>=2.14.0
|
|
@@ -50,6 +49,7 @@ Requires-Dist: websockets>=14.0
|
|
|
50
49
|
Requires-Dist: xmltodict>=1.0.2
|
|
51
50
|
Provides-Extra: all
|
|
52
51
|
Requires-Dist: confusables<2.0.0,>=1.2.0; extra == 'all'
|
|
52
|
+
Requires-Dist: moviepy<3.0.0,>=2.1.2; extra == 'all'
|
|
53
53
|
Requires-Dist: nltk<4.0.0,>=3.9.1; extra == 'all'
|
|
54
54
|
Requires-Dist: presidio-analyzer<3.0.0,>=2.2.359; extra == 'all'
|
|
55
55
|
Requires-Dist: python-jsonpath>=2.0.1; extra == 'all'
|
|
@@ -75,6 +75,8 @@ Requires-Dist: textstat<1.0.0,>=0.7.10; extra == 'scoring'
|
|
|
75
75
|
Provides-Extra: training
|
|
76
76
|
Requires-Dist: ray[default,serve]<3.0.0,>=2.10.0; extra == 'training'
|
|
77
77
|
Requires-Dist: torch>=2.9.0; extra == 'training'
|
|
78
|
+
Provides-Extra: video
|
|
79
|
+
Requires-Dist: moviepy<3.0.0,>=2.1.2; extra == 'video'
|
|
78
80
|
Description-Content-Type: text/markdown
|
|
79
81
|
|
|
80
82
|
<p align="center">
|
|
@@ -194,6 +194,11 @@ class Agent(Executor[AgentEvent, Trajectory]):
|
|
|
194
194
|
# Private state
|
|
195
195
|
_generator: Generator | None = PrivateAttr(None, init=False)
|
|
196
196
|
_current_input: str = PrivateAttr("", init=False)
|
|
197
|
+
_capability: tuple[str, str] | None = PrivateAttr(None, init=False)
|
|
198
|
+
"""The (name, version) capability this agent runs under, if any. Bound to
|
|
199
|
+
``current_capability`` for the duration of a run (and reset afterward) so
|
|
200
|
+
runtime tools attribute emitted items to the right producer without leaking
|
|
201
|
+
attribution into later agents that share the async context."""
|
|
197
202
|
_permission_bridge: PermissionBridge | None = PrivateAttr(None, init=False)
|
|
198
203
|
"""Tool-approval bridge injected by the runtime so foreign engines wire their
|
|
199
204
|
permission callback into the native HITL path. ``None`` for bare-SDK use."""
|
|
@@ -1204,6 +1209,13 @@ class Agent(Executor[AgentEvent, Trajectory]):
|
|
|
1204
1209
|
active_trajectory = self.trajectory
|
|
1205
1210
|
|
|
1206
1211
|
async with AsyncExitStack() as stack:
|
|
1212
|
+
# Scope capability attribution to THIS run (reset on exit) so it never
|
|
1213
|
+
# leaks into a later agent sharing the async context.
|
|
1214
|
+
if self._capability is not None:
|
|
1215
|
+
from dreadnode.tracing.span import bind_capability
|
|
1216
|
+
|
|
1217
|
+
stack.enter_context(bind_capability(self._capability))
|
|
1218
|
+
|
|
1207
1219
|
# Enter tool contexts
|
|
1208
1220
|
for tool_container in self.tools:
|
|
1209
1221
|
if hasattr(tool_container, "__aenter__") and hasattr(tool_container, "__aexit__"):
|
|
@@ -5,6 +5,7 @@ Similar to Claude Code's Task tool, this allows spawning specialized agents
|
|
|
5
5
|
to handle specific subtasks autonomously.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
+
import asyncio
|
|
8
9
|
import typing as t
|
|
9
10
|
from textwrap import dedent
|
|
10
11
|
|
|
@@ -93,8 +94,11 @@ class SubAgentToolset(Toolset):
|
|
|
93
94
|
parent_agent: t.Any = Config(default=None)
|
|
94
95
|
"""The parent agent to clone sub-agents from."""
|
|
95
96
|
|
|
96
|
-
|
|
97
|
-
"""
|
|
97
|
+
timeout: float | None = Config(default=3600.0)
|
|
98
|
+
"""Maximum seconds a spawned sub-agent may run before it is cancelled and
|
|
99
|
+
reported as a timeout. ``None`` disables the ceiling (unbounded). A wedged
|
|
100
|
+
tool inside a sub-agent (hung MCP transport, stuck LLM stream) would
|
|
101
|
+
otherwise hang the parent session indefinitely."""
|
|
98
102
|
|
|
99
103
|
@tool_method
|
|
100
104
|
async def spawn_agent(
|
|
@@ -126,7 +130,6 @@ class SubAgentToolset(Toolset):
|
|
|
126
130
|
- Complex tasks requiring focused work
|
|
127
131
|
- Exploration that might take many steps
|
|
128
132
|
- Tasks where you want isolated context
|
|
129
|
-
- Parallel work (with run_in_background)
|
|
130
133
|
|
|
131
134
|
## Examples
|
|
132
135
|
|
|
@@ -173,7 +176,37 @@ class SubAgentToolset(Toolset):
|
|
|
173
176
|
sub_agent.reset()
|
|
174
177
|
|
|
175
178
|
try:
|
|
176
|
-
|
|
179
|
+
# Bound the sub-agent run so a wedged tool inside it can't hang the
|
|
180
|
+
# parent session forever. ``asyncio.timeout(None)`` is a no-op, so a
|
|
181
|
+
# single path covers both the bounded and unbounded cases. On expiry
|
|
182
|
+
# it cancels the inner run and raises ``TimeoutError`` here; the
|
|
183
|
+
# ``CancelledError`` it uses internally never escapes. We check
|
|
184
|
+
# ``cm.expired()`` to tell our ceiling breach apart from a builtin
|
|
185
|
+
# ``TimeoutError`` raised *inside* the sub-agent, and deliberately do
|
|
186
|
+
# NOT catch ``CancelledError`` (a genuine parent-step cancellation
|
|
187
|
+
# must propagate, not be swallowed into a tool result).
|
|
188
|
+
async with asyncio.timeout(self.timeout) as cm:
|
|
189
|
+
trajectory = await sub_agent.run(task)
|
|
190
|
+
except TimeoutError as e:
|
|
191
|
+
if not cm.expired():
|
|
192
|
+
# A builtin ``TimeoutError`` from within the sub-agent (socket,
|
|
193
|
+
# inner ``async_timeout``, …) — not our ceiling. Surface it as an
|
|
194
|
+
# ordinary failure rather than a false "cancelled at ceiling".
|
|
195
|
+
logger.error(f"Sub-agent failed: {e}")
|
|
196
|
+
return f"Sub-agent failed: {e}"
|
|
197
|
+
logger.warning("Sub-agent '{}' timed out after {}s", config["name"], self.timeout)
|
|
198
|
+
# The cancelled run still burned tokens; carry its partial cost so
|
|
199
|
+
# the parent session's accounting isn't understated.
|
|
200
|
+
return self._tool_result(
|
|
201
|
+
f"Sub-agent '{config['name']}' timed out after {self.timeout} seconds "
|
|
202
|
+
"and was cancelled. Consider narrowing the task or raising the "
|
|
203
|
+
"SubAgentToolset timeout.",
|
|
204
|
+
sub_agent.trajectory,
|
|
205
|
+
)
|
|
206
|
+
except Exception as e:
|
|
207
|
+
logger.error(f"Sub-agent failed: {e}")
|
|
208
|
+
return f"Sub-agent failed: {e}"
|
|
209
|
+
else:
|
|
177
210
|
# Get the last assistant message content as the response
|
|
178
211
|
last_message = trajectory.messages[-1] if trajectory.messages else None
|
|
179
212
|
response = str(last_message.content) if last_message else ""
|
|
@@ -185,17 +218,17 @@ class SubAgentToolset(Toolset):
|
|
|
185
218
|
result += f"**Result:**\n{response}"
|
|
186
219
|
|
|
187
220
|
logger.info(f"Sub-agent completed in {len(trajectory.steps)} steps")
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
221
|
+
return self._tool_result(result, trajectory)
|
|
222
|
+
|
|
223
|
+
@staticmethod
|
|
224
|
+
def _tool_result(content: str, trajectory: t.Any) -> Message:
|
|
225
|
+
"""Build the tool-result message, stashing the sub-agent's LLM cost on
|
|
226
|
+
its metadata so the agent framework can lift it onto the ``ToolEnd``
|
|
227
|
+
event and the TUI can display it in the parent session's footer."""
|
|
228
|
+
msg = Message(role="tool", content=content)
|
|
229
|
+
if trajectory.usage.cost_usd is not None:
|
|
230
|
+
msg.metadata["subagent_cost_usd"] = trajectory.usage.cost_usd
|
|
231
|
+
return msg
|
|
199
232
|
|
|
200
233
|
|
|
201
234
|
def create_subagent_tool(parent_agent: "Agent") -> SubAgentToolset:
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Canonical multimodal message parts for AI Red Teaming.
|
|
3
|
+
|
|
4
|
+
A trial's input (candidate) and output (response) are represented as an ordered list of
|
|
5
|
+
``MessagePart`` dicts. Text parts carry their text inline; media parts (image/audio/video)
|
|
6
|
+
carry a *content-addressed reference* to bytes stored once on the trial span
|
|
7
|
+
(``span.log_artifact`` → ``sha256:`` oid in ``dreadnode.artifacts``), never inline base64.
|
|
8
|
+
|
|
9
|
+
The shape is a lossless superset of the OpenAI / Anthropic / Gemini content-part models
|
|
10
|
+
(discriminated ``source`` union: artifact | url | file_id) so it round-trips faithfully and
|
|
11
|
+
the platform can resolve refs to presigned inline URLs for display.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import io
|
|
15
|
+
import tempfile
|
|
16
|
+
import typing as t
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
from loguru import logger
|
|
20
|
+
|
|
21
|
+
if t.TYPE_CHECKING:
|
|
22
|
+
from dreadnode.core.types import Audio, Image, Video
|
|
23
|
+
from dreadnode.tracing.span import TaskSpan
|
|
24
|
+
|
|
25
|
+
_MIME_BY_EXT = {
|
|
26
|
+
"png": "image/png",
|
|
27
|
+
"jpg": "image/jpeg",
|
|
28
|
+
"jpeg": "image/jpeg",
|
|
29
|
+
"gif": "image/gif",
|
|
30
|
+
"webp": "image/webp",
|
|
31
|
+
"bmp": "image/bmp",
|
|
32
|
+
"mp3": "audio/mpeg",
|
|
33
|
+
"wav": "audio/wav",
|
|
34
|
+
"ogg": "audio/ogg",
|
|
35
|
+
"flac": "audio/flac",
|
|
36
|
+
"m4a": "audio/mp4",
|
|
37
|
+
"mp4": "video/mp4",
|
|
38
|
+
"webm": "video/webm",
|
|
39
|
+
"mov": "video/quicktime",
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _mime_for_extension(ext: str | None, default: str) -> str:
|
|
44
|
+
if not ext:
|
|
45
|
+
return default
|
|
46
|
+
return _MIME_BY_EXT.get(ext.lower().lstrip("."), default)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def text_part(
|
|
50
|
+
text: str,
|
|
51
|
+
*,
|
|
52
|
+
transform: str | None = None,
|
|
53
|
+
variant: str | None = None,
|
|
54
|
+
) -> dict[str, t.Any]:
|
|
55
|
+
"""Build a canonical text message part.
|
|
56
|
+
|
|
57
|
+
``transform``/``variant`` record provenance when a *text* transform was
|
|
58
|
+
applied, so the UI can attribute the transform to the text part (not only
|
|
59
|
+
to image/audio/video parts).
|
|
60
|
+
"""
|
|
61
|
+
part: dict[str, t.Any] = {"kind": "text", "text": text}
|
|
62
|
+
if transform:
|
|
63
|
+
part["transform"] = transform
|
|
64
|
+
if variant:
|
|
65
|
+
part["variant"] = variant
|
|
66
|
+
return part
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _store_bytes_as_artifact(
|
|
70
|
+
span: "TaskSpan",
|
|
71
|
+
data: bytes,
|
|
72
|
+
*,
|
|
73
|
+
filename: str,
|
|
74
|
+
) -> dict[str, t.Any] | None:
|
|
75
|
+
"""Persist bytes as a content-addressed span artifact, return the artifact metadata.
|
|
76
|
+
|
|
77
|
+
The artifact's MIME type is inferred from ``filename`` by ``log_artifact``; the
|
|
78
|
+
caller supplies the canonical ``media_type`` on the resulting part separately.
|
|
79
|
+
"""
|
|
80
|
+
suffix = Path(filename).suffix or ""
|
|
81
|
+
try:
|
|
82
|
+
with tempfile.NamedTemporaryFile(suffix=suffix, delete=False) as tmp:
|
|
83
|
+
tmp.write(data)
|
|
84
|
+
tmp_path = Path(tmp.name)
|
|
85
|
+
try:
|
|
86
|
+
return span.log_artifact(tmp_path, name=filename)
|
|
87
|
+
finally:
|
|
88
|
+
tmp_path.unlink(missing_ok=True)
|
|
89
|
+
except Exception:
|
|
90
|
+
# Storage may be unconfigured (e.g. local unit tests) — degrade to no media ref
|
|
91
|
+
# rather than failing the trial. The text parts still carry the attack content.
|
|
92
|
+
logger.debug("Failed to store media artifact for message part", exc_info=True)
|
|
93
|
+
return None
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def _media_part(
|
|
97
|
+
span: "TaskSpan",
|
|
98
|
+
data: bytes,
|
|
99
|
+
*,
|
|
100
|
+
kind: str,
|
|
101
|
+
media_type: str,
|
|
102
|
+
filename: str,
|
|
103
|
+
transform: str | None,
|
|
104
|
+
variant: str | None,
|
|
105
|
+
caption: str | None,
|
|
106
|
+
) -> dict[str, t.Any]:
|
|
107
|
+
"""Build a media message part, storing bytes as a content-addressed artifact."""
|
|
108
|
+
meta = _store_bytes_as_artifact(span, data, filename=filename)
|
|
109
|
+
source: dict[str, t.Any] = {
|
|
110
|
+
"ref": "artifact",
|
|
111
|
+
"media_type": (meta.get("mime_type") if meta else None) or media_type,
|
|
112
|
+
"byte_size": (meta.get("size") if meta else None) or len(data),
|
|
113
|
+
"filename": (meta.get("name") if meta else None) or filename,
|
|
114
|
+
}
|
|
115
|
+
if meta and meta.get("oid"):
|
|
116
|
+
source["artifact_oid"] = meta["oid"]
|
|
117
|
+
part: dict[str, t.Any] = {"kind": kind, "source": source}
|
|
118
|
+
if transform:
|
|
119
|
+
part["transform"] = transform
|
|
120
|
+
if variant:
|
|
121
|
+
part["variant"] = variant
|
|
122
|
+
if caption:
|
|
123
|
+
part["caption"] = caption
|
|
124
|
+
return part
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def image_part(
|
|
128
|
+
span: "TaskSpan",
|
|
129
|
+
image: "Image",
|
|
130
|
+
*,
|
|
131
|
+
transform: str | None = None,
|
|
132
|
+
variant: str | None = None,
|
|
133
|
+
filename: str = "image.png",
|
|
134
|
+
) -> dict[str, t.Any]:
|
|
135
|
+
"""Build an image message part from an ``Image``, storing its bytes as an artifact."""
|
|
136
|
+
try:
|
|
137
|
+
data, metadata = image.to_serializable()
|
|
138
|
+
media_type = _mime_for_extension(metadata.get("extension"), "image/png")
|
|
139
|
+
caption = metadata.get("caption")
|
|
140
|
+
except Exception:
|
|
141
|
+
buffer = io.BytesIO()
|
|
142
|
+
image.to_pil().save(buffer, format="PNG")
|
|
143
|
+
data, media_type, caption = buffer.getvalue(), "image/png", None
|
|
144
|
+
return _media_part(
|
|
145
|
+
span,
|
|
146
|
+
data,
|
|
147
|
+
kind="image",
|
|
148
|
+
media_type=media_type,
|
|
149
|
+
filename=filename,
|
|
150
|
+
transform=transform,
|
|
151
|
+
variant=variant,
|
|
152
|
+
caption=caption,
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def audio_part(
|
|
157
|
+
span: "TaskSpan",
|
|
158
|
+
audio: "Audio",
|
|
159
|
+
*,
|
|
160
|
+
transform: str | None = None,
|
|
161
|
+
variant: str | None = None,
|
|
162
|
+
filename: str = "audio",
|
|
163
|
+
) -> dict[str, t.Any]:
|
|
164
|
+
"""Build an audio message part from an ``Audio``, storing its bytes as an artifact."""
|
|
165
|
+
data, metadata = audio.to_serializable()
|
|
166
|
+
ext = metadata.get("extension", "mp3")
|
|
167
|
+
media_type = _mime_for_extension(ext, "audio/mpeg")
|
|
168
|
+
name = filename if Path(filename).suffix else f"{filename}.{ext}"
|
|
169
|
+
return _media_part(
|
|
170
|
+
span,
|
|
171
|
+
data,
|
|
172
|
+
kind="audio",
|
|
173
|
+
media_type=media_type,
|
|
174
|
+
filename=name,
|
|
175
|
+
transform=transform,
|
|
176
|
+
variant=variant,
|
|
177
|
+
caption=metadata.get("transcript"),
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def video_part(
|
|
182
|
+
span: "TaskSpan",
|
|
183
|
+
video: "Video",
|
|
184
|
+
*,
|
|
185
|
+
transform: str | None = None,
|
|
186
|
+
variant: str | None = None,
|
|
187
|
+
filename: str = "video",
|
|
188
|
+
) -> dict[str, t.Any]:
|
|
189
|
+
"""Build a video message part from a ``Video``, storing its bytes as an artifact."""
|
|
190
|
+
data, metadata = video.to_serializable()
|
|
191
|
+
ext = metadata.get("extension", "mp4")
|
|
192
|
+
media_type = _mime_for_extension(ext, "video/mp4")
|
|
193
|
+
name = filename if Path(filename).suffix else f"{filename}.{ext}"
|
|
194
|
+
return _media_part(
|
|
195
|
+
span,
|
|
196
|
+
data,
|
|
197
|
+
kind="video",
|
|
198
|
+
media_type=media_type,
|
|
199
|
+
filename=name,
|
|
200
|
+
transform=transform,
|
|
201
|
+
variant=variant,
|
|
202
|
+
caption=None,
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def modality_from_parts(parts: list[dict[str, t.Any]]) -> str:
|
|
207
|
+
"""Derive input_modality from the kinds present in a part list."""
|
|
208
|
+
kinds = {str(p.get("kind")) for p in parts if p.get("kind")}
|
|
209
|
+
media = kinds - {"text"}
|
|
210
|
+
if not media:
|
|
211
|
+
return "text"
|
|
212
|
+
if len(media) == 1:
|
|
213
|
+
return next(iter(media)) # "image" | "audio" | "video"
|
|
214
|
+
return "multimodal"
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def response_to_parts(
|
|
218
|
+
span: "TaskSpan",
|
|
219
|
+
response: t.Any,
|
|
220
|
+
) -> list[dict[str, t.Any]]:
|
|
221
|
+
"""
|
|
222
|
+
Build response message parts from a target's output.
|
|
223
|
+
|
|
224
|
+
Handles text-out targets (str), media-out targets (Image/Audio/Video), and mixed
|
|
225
|
+
outputs (a Message, or a list/dict containing media). Media bytes are stored as
|
|
226
|
+
content-addressed artifacts; text is inlined.
|
|
227
|
+
"""
|
|
228
|
+
from dreadnode.core.types import Audio, Image, Video
|
|
229
|
+
|
|
230
|
+
parts: list[dict[str, t.Any]] = []
|
|
231
|
+
|
|
232
|
+
def _walk(value: t.Any) -> None:
|
|
233
|
+
if value is None:
|
|
234
|
+
return
|
|
235
|
+
if isinstance(value, str):
|
|
236
|
+
if value:
|
|
237
|
+
parts.append(text_part(value))
|
|
238
|
+
elif isinstance(value, Image):
|
|
239
|
+
parts.append(image_part(span, value, variant="output", filename="response.png"))
|
|
240
|
+
elif isinstance(value, Audio):
|
|
241
|
+
parts.append(audio_part(span, value, variant="output", filename="response"))
|
|
242
|
+
elif isinstance(value, Video):
|
|
243
|
+
parts.append(video_part(span, value, variant="output", filename="response"))
|
|
244
|
+
elif isinstance(value, dict):
|
|
245
|
+
# A Message-like dict or provider payload — walk content/parts if present.
|
|
246
|
+
for key in ("content", "content_parts", "parts", "text"):
|
|
247
|
+
if key in value:
|
|
248
|
+
_walk(value[key])
|
|
249
|
+
return
|
|
250
|
+
parts.append(text_part(str(value)))
|
|
251
|
+
elif isinstance(value, (list, tuple)):
|
|
252
|
+
for item in value:
|
|
253
|
+
_walk(item)
|
|
254
|
+
else:
|
|
255
|
+
# Message object or unknown — try content_parts, else stringify.
|
|
256
|
+
content = getattr(value, "content_parts", None) or getattr(value, "content", None)
|
|
257
|
+
if content is not None and not isinstance(content, str):
|
|
258
|
+
_walk(content)
|
|
259
|
+
else:
|
|
260
|
+
parts.append(text_part(str(value)))
|
|
261
|
+
|
|
262
|
+
_walk(response)
|
|
263
|
+
return parts or [text_part("")]
|