dreadnode 2.0.9__tar.gz → 2.0.11__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.9 → dreadnode-2.0.11}/PKG-INFO +2 -2
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/agents/agent.py +141 -15
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/agents/events.py +27 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/agents/hooks.py +4 -75
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/agents/tools.py +4 -2
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/beast.py +3 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/crescendo.py +3 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/deep_inception.py +3 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/drattack.py +3 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/goat.py +3 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/gptfuzzer.py +3 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/pair.py +3 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/rainbow.py +3 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/renellm.py +3 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/api/client.py +61 -26
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/api/models.py +31 -12
- dreadnode-2.0.11/dreadnode/app/cli/airt.py +1057 -0
- dreadnode-2.0.11/dreadnode/app/cli/capability.py +1218 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/cli/evaluation.py +120 -2
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/cli/shared.py +5 -1
- dreadnode-2.0.11/dreadnode/app/cli/task.py +2277 -0
- dreadnode-2.0.11/dreadnode/app/cli/templates/__init__.py +1 -0
- dreadnode-2.0.11/dreadnode/app/cli/templates/init/__init__.py +1 -0
- dreadnode-2.0.11/dreadnode/app/cli/templates/init/challenge/Dockerfile +4 -0
- dreadnode-2.0.11/dreadnode/app/cli/templates/init/docker-compose.yaml +10 -0
- dreadnode-2.0.11/dreadnode/app/cli/templates/init/provision.sh +27 -0
- dreadnode-2.0.11/dreadnode/app/cli/templates/init/solution.sh +21 -0
- dreadnode-2.0.11/dreadnode/app/cli/templates/init/task-remote.yaml.tmpl +120 -0
- dreadnode-2.0.11/dreadnode/app/cli/templates/init/task.yaml.tmpl +99 -0
- dreadnode-2.0.11/dreadnode/app/cli/templates/init/teardown.sh +22 -0
- dreadnode-2.0.11/dreadnode/app/cli/templates/init/verify.sh +28 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/config.py +2 -1
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/main.py +1 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/server/app.py +302 -49
- dreadnode-2.0.11/dreadnode/app/server/prompt.py +217 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/app.py +687 -80
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/client.py +12 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/commands.py +7 -1
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/dreadnode.tcss +141 -33
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/event_contract.py +22 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/screens/__init__.py +6 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/screens/auth.py +6 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/screens/base.py +1 -1
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/screens/capabilities.py +185 -147
- dreadnode-2.0.11/dreadnode/app/tui/screens/capability_docs.py +301 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/screens/environments.py +185 -24
- dreadnode-2.0.11/dreadnode/app/tui/screens/models.py +875 -0
- dreadnode-2.0.11/dreadnode/app/tui/screens/raw_spans.py +186 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/screens/runtimes.py +310 -153
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/screens/sessions.py +12 -2
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/screens/workspaces.py +104 -13
- dreadnode-2.0.11/dreadnode/app/tui/spans_reader.py +134 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/widgets/composer.py +36 -6
- dreadnode-2.0.11/dreadnode/builtin_capabilities/__init__.py +79 -0
- dreadnode-2.0.11/dreadnode/builtin_capabilities/dreadnode/agents/dreadnode.md +54 -0
- dreadnode-2.0.11/dreadnode/builtin_capabilities/dreadnode/capability.yaml +4 -0
- dreadnode-2.0.11/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-runtime-reference/SKILL.md +78 -0
- dreadnode-2.0.11/dreadnode/builtin_capabilities/dreadnode/system-prompt.md +7 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/generators/generator/base.py +7 -0
- dreadnode-2.0.11/dreadnode/optimization/adapters/stack.py +601 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/optimization/backends/gepa.py +2 -1
- dreadnode-2.0.11/dreadnode/packaging/task_validation.py +993 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/skills/creating-capabilities/SKILL.md +6 -0
- dreadnode-2.0.11/dreadnode/skills/creating-capabilities/capability-improvement.md +339 -0
- dreadnode-2.0.11/dreadnode/skills/creating-capabilities/runtime-default-capability.md +262 -0
- dreadnode-2.0.11/dreadnode/skills/dreadnode-cli/SKILL.md +109 -0
- dreadnode-2.0.11/dreadnode/skills/dreadnode-cli/references/command-groups.md +224 -0
- dreadnode-2.0.11/dreadnode/skills/dreadnode-cli/references/tui-crosswalk.md +27 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/tools/__init__.py +35 -9
- dreadnode-2.0.11/dreadnode/tools/dreadnode_cli.py +63 -0
- dreadnode-2.0.11/dreadnode/tools/report.py +95 -0
- dreadnode-2.0.11/dreadnode/tools/trajectory_search.py +63 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/recipes.py +7 -5
- {dreadnode-2.0.9 → dreadnode-2.0.11}/pyproject.toml +2 -2
- dreadnode-2.0.9/dreadnode/app/cli/airt.py +0 -415
- dreadnode-2.0.9/dreadnode/app/cli/capability.py +0 -610
- dreadnode-2.0.9/dreadnode/app/cli/task.py +0 -868
- dreadnode-2.0.9/dreadnode/app/server/prompt.py +0 -182
- dreadnode-2.0.9/dreadnode/packaging/task_validation.py +0 -475
- {dreadnode-2.0.9 → dreadnode-2.0.11}/.gitignore +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/LICENSE +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/README.md +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/__main__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/agents/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/agents/exceptions.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/agents/format.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/agents/mcp/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/agents/mcp/auth.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/agents/mcp/client.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/agents/mcp/config.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/agents/mcp/server.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/agents/reactions.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/agents/skills.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/agents/stopping.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/agents/subagent.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/agents/trajectory.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/analytics/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/analytics/aggregator.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/analytics/classifier.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/analytics/compliance.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/analytics/engine.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/analytics/recommendations.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/analytics/types.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/assessment.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/autodan_turbo.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/compliance/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/compliance/atlas.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/compliance/nist.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/compliance/owasp.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/compliance/owasp_agentic.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/compliance/saif.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/constants.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/data/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/data/assets/audio/adversarial_query.mp3 +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/data/assets/image/bomb.jpg +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/data/assets/image/meth.png +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/data/prompts/adversarial_benchmark_subset.csv +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/data/prompts/ai_safety.csv +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/data/rubrics/data_exfiltration.yaml +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/data/rubrics/goal_hijacking.yaml +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/data/rubrics/memory_poisoning.yaml +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/data/rubrics/privilege_escalation.yaml +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/data/rubrics/rce.yaml +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/data/rubrics/scope_creep.yaml +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/data/rubrics/tool_chaining.yaml +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/data/rubrics/tool_selection_safety.yaml +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/data/rubrics/unbounded_agency.yaml +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/data/rubrics/web_chatbot_security.yaml +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/data/templates/crescendo/variant_1.yaml +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/data/templates/crescendo/variant_2.yaml +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/data/templates/crescendo/variant_3.yaml +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/data/templates/crescendo/variant_4.yaml +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/data/templates/crescendo/variant_5.yaml +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/events.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/image.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/multimodal.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/prompt.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/reporting/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/reporting/json_report.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/reporting/llm_summary.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/reporting/markdown.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/airt/tap.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/api/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/cli/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/cli/args.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/cli/dataset.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/cli/main.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/cli/model.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/cli/optimize.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/cli/runtime.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/cli/sandbox.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/cli/train.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/cli/worlds.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/model_catalog.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/print_mode.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/server/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/server/auth.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/server/utils.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/connection.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/model_variants.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/runtime_cache.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/screens/connection_error.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/screens/console.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/screens/evaluations.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/screens/mcp.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/screens/model_picker.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/screens/sandboxes.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/screens/secrets.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/screens/theme_showcase.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/screens/traces.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/theme.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/turn_lifecycle.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/turn_reducer.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/update_check.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/widgets/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/widgets/agent_dialog.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/widgets/agent_suggester.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/widgets/context_bar.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/widgets/conversation.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/widgets/flash.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/widgets/header_bar.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/widgets/help_panel.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/widgets/mention_overlay.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/widgets/message_queue.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/widgets/overlay_mixin.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/widgets/permission_prompt.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/widgets/profile_dialog.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/widgets/prompt_info.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/widgets/session_sidebar.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/widgets/skills_dialog.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/widgets/slash_overlay.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/widgets/status_bar.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/widgets/throbber.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/widgets/tool.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/widgets/tool_progress.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/widgets/tools_dialog.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/widgets/welcome.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/app/tui/widgets/whoami.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/capabilities/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/capabilities/capability.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/capabilities/loader.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/capabilities/sync.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/capabilities/tool_rules.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/capabilities/types.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/conditions.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/discovery.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/environment.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/exceptions.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/execution.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/hook.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/judge.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/load.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/log.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/meta/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/meta/config.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/meta/context.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/meta/hydrate.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/meta/introspect.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/metric.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/object.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/scorer.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/serialization.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/stopping.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/task.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/transforms.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/types/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/types/audio.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/types/base.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/types/common.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/types/image.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/types/object_3d.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/types/table.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/types/text.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/types/video.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/core/util.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/datasets/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/datasets/dataset.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/datasets/hf.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/datasets/local.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/evaluations/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/evaluations/console.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/evaluations/evaluation.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/evaluations/events.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/evaluations/format.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/evaluations/result.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/evaluations/sample.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/generators/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/generators/caching.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/generators/chat.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/generators/data.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/generators/exceptions.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/generators/generator/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/generators/generator/http.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/generators/generator/litellm_.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/generators/generator/transformers_.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/generators/generator/vllm_.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/generators/message.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/generators/models.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/generators/parsing.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/generators/tokenizer/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/generators/tokenizer/base.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/generators/tokenizer/transformers_.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/generators/utils.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/models/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/models/hf.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/models/local.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/models/model.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/optimization/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/optimization/adapters/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/optimization/adapters/agent.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/optimization/api.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/optimization/backends/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/optimization/backends/base.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/optimization/collectors.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/optimization/config.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/optimization/console.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/optimization/events.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/optimization/format.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/optimization/jobs.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/optimization/result.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/optimization/sampler.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/optimization/sampling.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/optimization/search.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/optimization/stopping.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/optimization/study.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/optimization/trial.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/packaging/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/packaging/loader.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/packaging/manifest.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/packaging/oci.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/packaging/package.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/py.typed +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/samplers/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/samplers/boundary.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/samplers/fuzzing.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/samplers/graph.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/samplers/grid.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/samplers/image.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/samplers/mapelites.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/samplers/optuna.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/samplers/random.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/samplers/registry.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/samplers/strategy.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/advanced_jailbreak_detection.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/agent_security.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/agentic.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/agentic_workflow.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/classification.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/consistency.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/contains.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/cosine_sim.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/credentials.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/crucible.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/documentation_security.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/exfiltration_detection.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/format.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/harm.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/ide_security.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/image.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/json.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/judge.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/length.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/lexical.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/mcp_security.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/memorization.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/multi_agent_security.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/pii.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/prompt_leak.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/readability.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/reasoning_security.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/sentiment.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/scorers/similarity.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/skills/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/skills/creating-capabilities/capability-components.md +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/storage/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/storage/providers.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/storage/session_store.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/storage/storage.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/tools/_ripgrep.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/tools/apply_patch.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/tools/editing.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/tools/execute.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/tools/fetch.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/tools/glob.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/tools/grep.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/tools/interaction.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/tools/ls.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/tools/memory.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/tools/read.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/tools/task.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/tools/think.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/tools/todo.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/tools/web_search.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/tools/write.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/tracing/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/tracing/constants.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/tracing/convert.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/tracing/exporter.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/tracing/exporters.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/tracing/span.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/tracing/spans.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/tracing/trace_converter.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/base.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/dpo.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/etl/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/etl/_common.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/etl/rl.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/etl/sft.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/etl/worlds.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/events.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/grpo.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/jobs.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/ppo.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/prime.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/ray/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/ray/async_trainer.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/ray/config.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/ray/coordinator.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/ray/distributed.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/ray/dpo.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/ray/experience.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/ray/fsdp2_learner.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/ray/inference.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/ray/learner.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/ray/multi_turn.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/ray/ppo.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/ray/reward_model.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/ray/rollout_env.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/ray/rollout_worker.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/ray/sft.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/ray/trainer.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/rewards/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/rewards/aggregator.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/rewards/functions.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/rewards/scorer_bridge.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/rewards/shaping.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/rewards/types.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/rollouts/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/rollouts/adapters.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/rollouts/orchestrator.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/rollouts/types.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/rollouts/worlds.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/serving/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/serving/vllm_client.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/sft.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/tinker/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/tinker/config.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/tinker/data.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/tinker/renderer.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/tinker/rl.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/tinker/trainer.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/tinker_sft.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/training/utils.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/__init__.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/advanced_jailbreak.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/adversarial_suffix.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/agent_skill.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/agentic_workflow.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/audio.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/browser_agent_attacks.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/cipher.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/constitutional.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/document.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/documentation_poison.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/encoding.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/exfiltration.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/flip_attack.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/guardrail_bypass.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/ide_injection.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/image.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/injection.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/json_tools.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/language.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/logic_bomb.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/mcp_attacks.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/multi_agent_attacks.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/persuasion.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/perturbation.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/pii_extraction.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/pythonic_tools.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/rag_poisoning.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/reasoning_attacks.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/refine.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/response_steering.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/stylistic.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/substitution.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/swap.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/system_prompt_extraction.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/text.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/video.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/dreadnode/transforms/xml_tools.py +0 -0
- {dreadnode-2.0.9 → dreadnode-2.0.11}/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.11
|
|
4
4
|
Summary: Dreadnode SDK
|
|
5
5
|
Project-URL: Homepage, https://dreadnode.io
|
|
6
6
|
Project-URL: Documentation, https://docs.dreadnode.io
|
|
@@ -19,7 +19,7 @@ Requires-Dist: gepa>=0.1.1
|
|
|
19
19
|
Requires-Dist: httpx<1.0.0,>=0.28.0
|
|
20
20
|
Requires-Dist: jsonpath-ng>=1.7.0
|
|
21
21
|
Requires-Dist: jsonref>=1.1.0
|
|
22
|
-
Requires-Dist: litellm<=1.
|
|
22
|
+
Requires-Dist: litellm<=1.83.0,>=1.83.0
|
|
23
23
|
Requires-Dist: logfire<=3.20.0,>=3.5.3
|
|
24
24
|
Requires-Dist: loguru>=0.7.3
|
|
25
25
|
Requires-Dist: mcp<2.0.0,>=1.25.0
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
import contextlib
|
|
2
3
|
import inspect
|
|
4
|
+
import random
|
|
5
|
+
import time
|
|
3
6
|
import typing as t
|
|
4
|
-
from contextlib import AsyncExitStack, asynccontextmanager,
|
|
7
|
+
from contextlib import AsyncExitStack, asynccontextmanager, suppress
|
|
5
8
|
from copy import deepcopy
|
|
6
9
|
from pathlib import Path
|
|
7
10
|
from textwrap import dedent
|
|
@@ -30,6 +33,7 @@ from dreadnode.agents.events import (
|
|
|
30
33
|
GenerationContent,
|
|
31
34
|
GenerationEnd,
|
|
32
35
|
GenerationError,
|
|
36
|
+
GenerationRetry,
|
|
33
37
|
GenerationStart,
|
|
34
38
|
GenerationStep,
|
|
35
39
|
ReactStep,
|
|
@@ -80,6 +84,45 @@ def _raise_exception(error: BaseException) -> t.NoReturn:
|
|
|
80
84
|
raise error
|
|
81
85
|
|
|
82
86
|
|
|
87
|
+
_TRANSIENT_LITELLM_EXCEPTION_NAMES: tuple[str, ...] = (
|
|
88
|
+
"RateLimitError",
|
|
89
|
+
"Timeout",
|
|
90
|
+
"APIConnectionError",
|
|
91
|
+
"APIConnectionTimeoutError",
|
|
92
|
+
"ServiceUnavailableError",
|
|
93
|
+
"InternalServerError",
|
|
94
|
+
"BadGatewayError",
|
|
95
|
+
"APIError",
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _is_transient_api_error(error: BaseException) -> bool:
|
|
100
|
+
"""Classify an error as a transient LLM API failure worth retrying.
|
|
101
|
+
|
|
102
|
+
Matches an explicit allow-list of ``litellm.exceptions`` classes that
|
|
103
|
+
represent recoverable conditions: rate limits, timeouts, connection
|
|
104
|
+
failures, and 5xx responses. Notably **does not** match
|
|
105
|
+
``BadRequestError``, ``AuthenticationError``,
|
|
106
|
+
``ContextWindowExceededError`` (handled by overflow recovery), or other
|
|
107
|
+
deterministic client errors.
|
|
108
|
+
|
|
109
|
+
The allow-list is walked dynamically because ``litellm.exceptions`` does
|
|
110
|
+
not expose a single common ancestor for its transient exceptions.
|
|
111
|
+
Returns ``False`` if ``litellm`` is not importable.
|
|
112
|
+
"""
|
|
113
|
+
with contextlib.suppress(ImportError):
|
|
114
|
+
import litellm.exceptions as _litellm_exc
|
|
115
|
+
|
|
116
|
+
classes = tuple(
|
|
117
|
+
cls
|
|
118
|
+
for name in _TRANSIENT_LITELLM_EXCEPTION_NAMES
|
|
119
|
+
if (cls := getattr(_litellm_exc, name, None)) is not None
|
|
120
|
+
)
|
|
121
|
+
if classes and isinstance(error, classes):
|
|
122
|
+
return True
|
|
123
|
+
return False
|
|
124
|
+
|
|
125
|
+
|
|
83
126
|
class Agent(Executor[AgentEvent, Trajectory]):
|
|
84
127
|
"""
|
|
85
128
|
Agent abstraction for applying tools, event logic, and message state to LLM generation.
|
|
@@ -128,6 +171,14 @@ class Agent(Executor[AgentEvent, Trajectory]):
|
|
|
128
171
|
"""Extra parameters merged into GenerateParams for every generation (e.g. thinking config)."""
|
|
129
172
|
working_dir: Path | None = Config(default=None)
|
|
130
173
|
"""Working directory used for tool output offloading and other IO."""
|
|
174
|
+
backoff_max_tries: int = Config(default=8, ge=0)
|
|
175
|
+
"""Maximum retries on transient LLM API errors per step. ``0`` disables retry."""
|
|
176
|
+
backoff_max_time: float = Config(default=300.0, ge=0)
|
|
177
|
+
"""Maximum total seconds to spend retrying transient LLM API errors per step."""
|
|
178
|
+
backoff_base_factor: float = Config(default=1.0, ge=0)
|
|
179
|
+
"""Base factor for exponential backoff: wait = base_factor * 2 ** (attempt - 1)."""
|
|
180
|
+
backoff_jitter: bool = Config(default=True)
|
|
181
|
+
"""Whether to add up to ``backoff_base_factor`` seconds of random jitter to each wait."""
|
|
131
182
|
|
|
132
183
|
# Private state
|
|
133
184
|
_generator: Generator | None = PrivateAttr(None, init=False)
|
|
@@ -381,6 +432,49 @@ class Agent(Executor[AgentEvent, Trajectory]):
|
|
|
381
432
|
|
|
382
433
|
raise winning_reaction
|
|
383
434
|
|
|
435
|
+
def _try_backoff(
|
|
436
|
+
self,
|
|
437
|
+
error: BaseException,
|
|
438
|
+
*,
|
|
439
|
+
tries: int,
|
|
440
|
+
start_time: float,
|
|
441
|
+
) -> float | None:
|
|
442
|
+
"""Compute a retry sleep for a transient LLM API error.
|
|
443
|
+
|
|
444
|
+
Returns the sleep duration in seconds if the caller should retry, or
|
|
445
|
+
``None`` if the error is not transient, tries are exhausted, or the
|
|
446
|
+
per-step time budget has been spent. Caller owns sleeping and emitting
|
|
447
|
+
the ``GenerationRetry`` event. Backoff is agent-owned at the error
|
|
448
|
+
site, mirroring ``_try_overflow_recovery`` — no step is consumed and
|
|
449
|
+
no hook indirection is involved.
|
|
450
|
+
"""
|
|
451
|
+
if self.backoff_max_tries <= 0:
|
|
452
|
+
return None
|
|
453
|
+
|
|
454
|
+
if not _is_transient_api_error(error):
|
|
455
|
+
return None
|
|
456
|
+
|
|
457
|
+
if tries >= self.backoff_max_tries:
|
|
458
|
+
logger.warning("Backoff aborted: max tries ({}) exceeded.", self.backoff_max_tries)
|
|
459
|
+
return None
|
|
460
|
+
|
|
461
|
+
remaining = self.backoff_max_time - (time.monotonic() - start_time)
|
|
462
|
+
if remaining <= 0:
|
|
463
|
+
logger.warning("Backoff aborted: max time ({:.2f}s) exceeded.", self.backoff_max_time)
|
|
464
|
+
return None
|
|
465
|
+
|
|
466
|
+
seconds = self.backoff_base_factor * (2**tries)
|
|
467
|
+
if self.backoff_jitter:
|
|
468
|
+
seconds += random.uniform(0, self.backoff_base_factor)
|
|
469
|
+
if seconds > remaining:
|
|
470
|
+
logger.warning(
|
|
471
|
+
"Backoff aborted: next sleep ({:.2f}s) would exceed remaining budget ({:.2f}s).",
|
|
472
|
+
seconds,
|
|
473
|
+
remaining,
|
|
474
|
+
)
|
|
475
|
+
return None
|
|
476
|
+
return seconds
|
|
477
|
+
|
|
384
478
|
async def _try_overflow_recovery(
|
|
385
479
|
self,
|
|
386
480
|
error: BaseException,
|
|
@@ -586,7 +680,7 @@ class Agent(Executor[AgentEvent, Trajectory]):
|
|
|
586
680
|
agent_name=self.name,
|
|
587
681
|
inputs={"goal": self._current_input},
|
|
588
682
|
params={
|
|
589
|
-
"session_id": str(
|
|
683
|
+
"session_id": str(traj.session_id),
|
|
590
684
|
"max_steps": self.max_steps,
|
|
591
685
|
**({"model": self.model_name} if self.model_name else {}),
|
|
592
686
|
**({"tools": [tool.name for tool in self.all_tools]} if self.all_tools else {}),
|
|
@@ -628,6 +722,43 @@ class Agent(Executor[AgentEvent, Trajectory]):
|
|
|
628
722
|
|
|
629
723
|
step_chat = await self._generate(messages)
|
|
630
724
|
|
|
725
|
+
# In-place transient-error backoff — rate limits and
|
|
726
|
+
# other litellm.APIError failures get retried at the
|
|
727
|
+
# error site with exponential backoff. No step budget
|
|
728
|
+
# consumed; clients observe GenerationRetry events
|
|
729
|
+
# rather than a spurious terminal GenerationError.
|
|
730
|
+
backoff_tries = 0
|
|
731
|
+
backoff_started = time.monotonic()
|
|
732
|
+
while step_chat.failed and step_chat.error:
|
|
733
|
+
wait = self._try_backoff(
|
|
734
|
+
step_chat.error,
|
|
735
|
+
tries=backoff_tries,
|
|
736
|
+
start_time=backoff_started,
|
|
737
|
+
)
|
|
738
|
+
if wait is None:
|
|
739
|
+
break
|
|
740
|
+
backoff_tries += 1
|
|
741
|
+
logger.warning(
|
|
742
|
+
"Backing off {:.2f}s (try {}/{})",
|
|
743
|
+
wait,
|
|
744
|
+
backoff_tries,
|
|
745
|
+
self.backoff_max_tries,
|
|
746
|
+
)
|
|
747
|
+
retry_event = GenerationRetry(
|
|
748
|
+
agent_id=self.agent_id,
|
|
749
|
+
agent_name=self.name,
|
|
750
|
+
step=step_count,
|
|
751
|
+
attempt=backoff_tries,
|
|
752
|
+
max_attempts=self.backoff_max_tries,
|
|
753
|
+
wait_seconds=wait,
|
|
754
|
+
error_type=type(step_chat.error).__name__,
|
|
755
|
+
error_message=str(step_chat.error),
|
|
756
|
+
)
|
|
757
|
+
async for event in self._dispatch(retry_event):
|
|
758
|
+
yield event
|
|
759
|
+
await asyncio.sleep(wait)
|
|
760
|
+
step_chat = await self._generate(messages)
|
|
761
|
+
|
|
631
762
|
# In-place overflow recovery — at most once per step,
|
|
632
763
|
# no step budget consumed, preserves step_count for
|
|
633
764
|
# user_message inclusion in trajectory.
|
|
@@ -683,7 +814,7 @@ class Agent(Executor[AgentEvent, Trajectory]):
|
|
|
683
814
|
)
|
|
684
815
|
|
|
685
816
|
# Check stop conditions INSIDE span
|
|
686
|
-
if any(cond(
|
|
817
|
+
if any(cond(traj.steps) for cond in self.stop_conditions):
|
|
687
818
|
logger.info("A stop condition was met. Ending run.")
|
|
688
819
|
gen_end = GenerationEnd(
|
|
689
820
|
agent_id=self.agent_id,
|
|
@@ -872,7 +1003,7 @@ class Agent(Executor[AgentEvent, Trajectory]):
|
|
|
872
1003
|
)
|
|
873
1004
|
|
|
874
1005
|
# Check stop conditions again INSIDE span
|
|
875
|
-
if any(cond(
|
|
1006
|
+
if any(cond(traj.steps) for cond in self.stop_conditions):
|
|
876
1007
|
break
|
|
877
1008
|
|
|
878
1009
|
except Continue as e:
|
|
@@ -899,7 +1030,7 @@ class Agent(Executor[AgentEvent, Trajectory]):
|
|
|
899
1030
|
stop_reason = "error"
|
|
900
1031
|
elif max_steps_reached:
|
|
901
1032
|
stop_reason = "max_steps_reached"
|
|
902
|
-
elif
|
|
1033
|
+
elif traj.steps and isinstance(traj.steps[-1], AgentStalled):
|
|
903
1034
|
stop_reason = "stalled"
|
|
904
1035
|
|
|
905
1036
|
async for event in self._dispatch(
|
|
@@ -961,17 +1092,12 @@ class Agent(Executor[AgentEvent, Trajectory]):
|
|
|
961
1092
|
if hasattr(tool_container, "__aenter__") and hasattr(tool_container, "__aexit__"):
|
|
962
1093
|
await stack.enter_async_context(tool_container)
|
|
963
1094
|
|
|
964
|
-
# Parent span only on new conversation (not when borrowing external trajectory)
|
|
965
1095
|
display_name = self.name or str(self.agent_id)[:8]
|
|
966
|
-
ctx = (
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
tags=["agent"],
|
|
972
|
-
)
|
|
973
|
-
if reset and trajectory is None
|
|
974
|
-
else nullcontext()
|
|
1096
|
+
ctx = dreadnode.task_span(
|
|
1097
|
+
f"agent:{display_name}",
|
|
1098
|
+
type="agent",
|
|
1099
|
+
label=display_name,
|
|
1100
|
+
tags=["agent"],
|
|
975
1101
|
)
|
|
976
1102
|
|
|
977
1103
|
with ctx as parent_span:
|
|
@@ -311,6 +311,32 @@ class CompactionEvent(AgentEvent):
|
|
|
311
311
|
}
|
|
312
312
|
|
|
313
313
|
|
|
314
|
+
class GenerationRetry(AgentEvent):
|
|
315
|
+
"""Lifecycle event: the agent is about to sleep and retry a failed generation.
|
|
316
|
+
|
|
317
|
+
Emitted by the agent loop when a transient LLM API error (rate limit, etc.)
|
|
318
|
+
is recovered in place via ``Agent._try_backoff``. This is a lifecycle signal
|
|
319
|
+
only — it does not consume a step or land in the trajectory.
|
|
320
|
+
"""
|
|
321
|
+
|
|
322
|
+
step: int
|
|
323
|
+
attempt: int
|
|
324
|
+
max_attempts: int
|
|
325
|
+
wait_seconds: float
|
|
326
|
+
error_type: str
|
|
327
|
+
error_message: str
|
|
328
|
+
|
|
329
|
+
def _get_data(self) -> dict[str, t.Any]:
|
|
330
|
+
return {
|
|
331
|
+
"step": self.step,
|
|
332
|
+
"attempt": self.attempt,
|
|
333
|
+
"max_attempts": self.max_attempts,
|
|
334
|
+
"wait_seconds": self.wait_seconds,
|
|
335
|
+
"error_type": self.error_type,
|
|
336
|
+
"error_message": self.error_message,
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
|
|
314
340
|
class AgentStalled(AgentEvent):
|
|
315
341
|
"""Event: The agent is stalled and there are no tool calls, or stop condition).
|
|
316
342
|
|
|
@@ -1017,6 +1043,7 @@ EVENT_TYPES: dict[str, type[AgentEvent]] = {
|
|
|
1017
1043
|
"GenerationStep": GenerationStep,
|
|
1018
1044
|
"GenerationContent": GenerationContent,
|
|
1019
1045
|
"GenerationError": GenerationError,
|
|
1046
|
+
"GenerationRetry": GenerationRetry,
|
|
1020
1047
|
"ReactStep": ReactStep,
|
|
1021
1048
|
"UserInputRequired": UserInputRequired,
|
|
1022
1049
|
"Heartbeat": Heartbeat,
|
|
@@ -1,19 +1,15 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Optional agent hooks: tool metrics and conversation summarization.
|
|
2
2
|
|
|
3
|
-
These hooks are
|
|
3
|
+
These hooks are opt-in — users register them explicitly on an ``Agent`` via
|
|
4
|
+
the ``hooks=`` constructor argument. Transient-error backoff is handled inline
|
|
5
|
+
by the agent loop (see ``Agent._try_backoff``) and is not a hook.
|
|
4
6
|
"""
|
|
5
7
|
|
|
6
|
-
import asyncio
|
|
7
8
|
import contextlib
|
|
8
|
-
import random
|
|
9
|
-
import time
|
|
10
9
|
import typing as t
|
|
11
10
|
from dataclasses import dataclass
|
|
12
11
|
|
|
13
|
-
from loguru import logger
|
|
14
|
-
|
|
15
12
|
from dreadnode.agents.events import (
|
|
16
|
-
AgentError,
|
|
17
13
|
AgentEvent,
|
|
18
14
|
AgentStep,
|
|
19
15
|
ToolEnd,
|
|
@@ -28,73 +24,6 @@ if t.TYPE_CHECKING:
|
|
|
28
24
|
from datetime import datetime
|
|
29
25
|
|
|
30
26
|
|
|
31
|
-
# =============================================================================
|
|
32
|
-
# Backoff
|
|
33
|
-
# =============================================================================
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def _make_backoff_hook(
|
|
37
|
-
exception_types: tuple[type[Exception], ...],
|
|
38
|
-
*,
|
|
39
|
-
max_tries: int = 8,
|
|
40
|
-
max_time: float = 300.0,
|
|
41
|
-
base_factor: float = 1.0,
|
|
42
|
-
jitter: bool = True,
|
|
43
|
-
):
|
|
44
|
-
"""Create a backoff hook for specific exception types."""
|
|
45
|
-
tries = 0
|
|
46
|
-
start_time: float | None = None
|
|
47
|
-
last_step_seen = -1
|
|
48
|
-
|
|
49
|
-
@hook(AgentEvent)
|
|
50
|
-
async def backoff_hook(event: AgentEvent) -> Reaction | None:
|
|
51
|
-
nonlocal tries, start_time, last_step_seen
|
|
52
|
-
|
|
53
|
-
if isinstance(event, AgentStep):
|
|
54
|
-
if event.step > last_step_seen:
|
|
55
|
-
tries = 0
|
|
56
|
-
start_time = None
|
|
57
|
-
last_step_seen = event.step
|
|
58
|
-
return None
|
|
59
|
-
|
|
60
|
-
if not isinstance(event, AgentError) or not isinstance(event.error, exception_types):
|
|
61
|
-
return None
|
|
62
|
-
|
|
63
|
-
if start_time is None:
|
|
64
|
-
start_time = time.monotonic()
|
|
65
|
-
|
|
66
|
-
if tries >= max_tries:
|
|
67
|
-
logger.warning(f"Backoff aborted: max tries ({max_tries}) exceeded.")
|
|
68
|
-
return None
|
|
69
|
-
|
|
70
|
-
if (time.monotonic() - start_time) >= max_time:
|
|
71
|
-
logger.warning(f"Backoff aborted: max time ({max_time:.2f}s) exceeded.")
|
|
72
|
-
return None
|
|
73
|
-
|
|
74
|
-
tries += 1
|
|
75
|
-
seconds = base_factor * (2 ** (tries - 1))
|
|
76
|
-
if jitter:
|
|
77
|
-
seconds += random.uniform(0, base_factor)
|
|
78
|
-
|
|
79
|
-
logger.warning(f"Backing off {seconds:.2f}s (try {tries}/{max_tries})")
|
|
80
|
-
await asyncio.sleep(seconds)
|
|
81
|
-
return Retry()
|
|
82
|
-
|
|
83
|
-
return backoff_hook
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
# Pre-instantiated for common LLM rate limit errors
|
|
87
|
-
backoff_on_ratelimit: Hook | None = None
|
|
88
|
-
try:
|
|
89
|
-
import litellm.exceptions
|
|
90
|
-
|
|
91
|
-
backoff_on_ratelimit = _make_backoff_hook(
|
|
92
|
-
(litellm.exceptions.RateLimitError, litellm.exceptions.APIError),
|
|
93
|
-
)
|
|
94
|
-
except ImportError:
|
|
95
|
-
pass
|
|
96
|
-
|
|
97
|
-
|
|
98
27
|
# =============================================================================
|
|
99
28
|
# Tool Metrics
|
|
100
29
|
# =============================================================================
|
|
@@ -170,7 +170,8 @@ async def offload_tool_output(
|
|
|
170
170
|
working_dir: Path,
|
|
171
171
|
) -> tuple[str, Path]:
|
|
172
172
|
"""Write tool output to disk and return middle-out summary plus file path."""
|
|
173
|
-
|
|
173
|
+
output_root = working_dir if working_dir.name == ".dreadnode" else working_dir / ".dreadnode"
|
|
174
|
+
output_dir = output_root / "tool-output"
|
|
174
175
|
await asyncio.to_thread(output_dir.mkdir, parents=True, exist_ok=True)
|
|
175
176
|
|
|
176
177
|
safe_id = re.sub(r"[^a-zA-Z0-9_-]", "_", tool_call_id)
|
|
@@ -178,7 +179,8 @@ async def offload_tool_output(
|
|
|
178
179
|
async with aiofiles.open(file_path, "w") as f:
|
|
179
180
|
await f.write(content)
|
|
180
181
|
|
|
181
|
-
|
|
182
|
+
relative_base = working_dir.parent if working_dir.name == ".dreadnode" else working_dir
|
|
183
|
+
relative_path = file_path.relative_to(relative_base)
|
|
182
184
|
|
|
183
185
|
half = OFFLOAD_THRESHOLD // 2
|
|
184
186
|
start = content[:half]
|
|
@@ -18,6 +18,7 @@ from dreadnode.airt.compliance import (
|
|
|
18
18
|
tag_attack,
|
|
19
19
|
)
|
|
20
20
|
from dreadnode.airt.prompt import OBJECTIVE_SCORE_KEY, _evaluate_prompt
|
|
21
|
+
from dreadnode.core.meta import TrialCandidate
|
|
21
22
|
from dreadnode.core.scorer import Scorer
|
|
22
23
|
from dreadnode.core.transforms import Transform, TransformsLike
|
|
23
24
|
from dreadnode.generators.generator import GenerateParams, Generator, get_generator
|
|
@@ -232,6 +233,7 @@ def beast_attack(
|
|
|
232
233
|
llm_judge(
|
|
233
234
|
evaluator_model,
|
|
234
235
|
rubric,
|
|
236
|
+
input=TrialCandidate(),
|
|
235
237
|
min_score=1,
|
|
236
238
|
max_score=10,
|
|
237
239
|
)
|
|
@@ -247,6 +249,7 @@ def beast_attack(
|
|
|
247
249
|
target=target,
|
|
248
250
|
fitted_transforms=fitted_transforms,
|
|
249
251
|
scorer=prompt_judge,
|
|
252
|
+
include_input=True,
|
|
250
253
|
)
|
|
251
254
|
|
|
252
255
|
attack = Study[str](
|
|
@@ -11,6 +11,7 @@ from dreadnode.airt.compliance import (
|
|
|
11
11
|
tag_attack,
|
|
12
12
|
)
|
|
13
13
|
from dreadnode.airt.prompt import OBJECTIVE_SCORE_KEY, _evaluate_prompt
|
|
14
|
+
from dreadnode.core.meta import TrialCandidate
|
|
14
15
|
from dreadnode.core.scorer import Scorer
|
|
15
16
|
from dreadnode.core.transforms import Transform, TransformsLike
|
|
16
17
|
from dreadnode.generators.generator import Generator, get_generator
|
|
@@ -221,6 +222,7 @@ Return ONLY the question text."""
|
|
|
221
222
|
llm_judge(
|
|
222
223
|
evaluator_model,
|
|
223
224
|
eval_rubric,
|
|
225
|
+
input=TrialCandidate(),
|
|
224
226
|
min_score=0,
|
|
225
227
|
max_score=1,
|
|
226
228
|
)
|
|
@@ -235,6 +237,7 @@ Return ONLY the question text."""
|
|
|
235
237
|
target=target,
|
|
236
238
|
fitted_transforms=fitted_transforms,
|
|
237
239
|
scorer=objective_judge,
|
|
240
|
+
include_input=True,
|
|
238
241
|
)
|
|
239
242
|
|
|
240
243
|
# Resolve model names for span attributes
|
|
@@ -18,6 +18,7 @@ from dreadnode.airt.compliance import (
|
|
|
18
18
|
tag_attack,
|
|
19
19
|
)
|
|
20
20
|
from dreadnode.airt.prompt import OBJECTIVE_SCORE_KEY, _evaluate_prompt
|
|
21
|
+
from dreadnode.core.meta import TrialCandidate
|
|
21
22
|
from dreadnode.core.scorer import Scorer
|
|
22
23
|
from dreadnode.core.transforms import Transform, TransformsLike
|
|
23
24
|
from dreadnode.generators.generator import Generator
|
|
@@ -135,6 +136,7 @@ def deep_inception_attack(
|
|
|
135
136
|
llm_judge(
|
|
136
137
|
evaluator_model,
|
|
137
138
|
rubric,
|
|
139
|
+
input=TrialCandidate(),
|
|
138
140
|
min_score=1,
|
|
139
141
|
max_score=10,
|
|
140
142
|
)
|
|
@@ -150,6 +152,7 @@ def deep_inception_attack(
|
|
|
150
152
|
target=target,
|
|
151
153
|
fitted_transforms=fitted_transforms,
|
|
152
154
|
scorer=prompt_judge,
|
|
155
|
+
include_input=True,
|
|
153
156
|
)
|
|
154
157
|
|
|
155
158
|
attack = Study[str](
|
|
@@ -19,6 +19,7 @@ from dreadnode.airt.compliance import (
|
|
|
19
19
|
tag_attack,
|
|
20
20
|
)
|
|
21
21
|
from dreadnode.airt.prompt import OBJECTIVE_SCORE_KEY, _evaluate_prompt
|
|
22
|
+
from dreadnode.core.meta import TrialCandidate
|
|
22
23
|
from dreadnode.core.scorer import Scorer
|
|
23
24
|
from dreadnode.core.transforms import Transform, TransformsLike
|
|
24
25
|
from dreadnode.generators.generator import GenerateParams, Generator, get_generator
|
|
@@ -137,6 +138,7 @@ def drattack(
|
|
|
137
138
|
llm_judge(
|
|
138
139
|
evaluator_model,
|
|
139
140
|
rubric,
|
|
141
|
+
input=TrialCandidate(),
|
|
140
142
|
min_score=1,
|
|
141
143
|
max_score=10,
|
|
142
144
|
)
|
|
@@ -152,6 +154,7 @@ def drattack(
|
|
|
152
154
|
target=target,
|
|
153
155
|
fitted_transforms=fitted_transforms,
|
|
154
156
|
scorer=prompt_judge,
|
|
157
|
+
include_input=True,
|
|
155
158
|
)
|
|
156
159
|
|
|
157
160
|
attack = Study[str](
|
|
@@ -8,6 +8,7 @@ from dreadnode.airt.compliance import (
|
|
|
8
8
|
tag_attack,
|
|
9
9
|
)
|
|
10
10
|
from dreadnode.airt.prompt import OBJECTIVE_SCORE_KEY, _evaluate_prompt
|
|
11
|
+
from dreadnode.core.meta import TrialCandidate
|
|
11
12
|
from dreadnode.core.scorer import Scorer
|
|
12
13
|
from dreadnode.core.transforms import Transform, TransformsLike
|
|
13
14
|
from dreadnode.generators.generator import Generator
|
|
@@ -114,6 +115,7 @@ def goat_attack(
|
|
|
114
115
|
llm_judge(
|
|
115
116
|
evaluator_model,
|
|
116
117
|
rubric,
|
|
118
|
+
input=TrialCandidate(),
|
|
117
119
|
min_score=1,
|
|
118
120
|
max_score=10,
|
|
119
121
|
)
|
|
@@ -141,6 +143,7 @@ def goat_attack(
|
|
|
141
143
|
target=target,
|
|
142
144
|
fitted_transforms=fitted_transforms,
|
|
143
145
|
scorer=prompt_judge,
|
|
146
|
+
include_input=True,
|
|
144
147
|
)
|
|
145
148
|
|
|
146
149
|
# Resolve model names for span attributes
|
|
@@ -17,6 +17,7 @@ from dreadnode.airt.compliance import (
|
|
|
17
17
|
tag_attack,
|
|
18
18
|
)
|
|
19
19
|
from dreadnode.airt.prompt import OBJECTIVE_SCORE_KEY, _evaluate_prompt
|
|
20
|
+
from dreadnode.core.meta import TrialCandidate
|
|
20
21
|
from dreadnode.core.scorer import Scorer
|
|
21
22
|
from dreadnode.core.transforms import Transform, TransformsLike
|
|
22
23
|
from dreadnode.generators.generator import Generator
|
|
@@ -150,6 +151,7 @@ def gptfuzzer_attack(
|
|
|
150
151
|
llm_judge(
|
|
151
152
|
evaluator_model,
|
|
152
153
|
rubric,
|
|
154
|
+
input=TrialCandidate(),
|
|
153
155
|
min_score=1,
|
|
154
156
|
max_score=10,
|
|
155
157
|
)
|
|
@@ -165,6 +167,7 @@ def gptfuzzer_attack(
|
|
|
165
167
|
target=target,
|
|
166
168
|
fitted_transforms=fitted_transforms,
|
|
167
169
|
scorer=prompt_judge,
|
|
170
|
+
include_input=True,
|
|
168
171
|
)
|
|
169
172
|
|
|
170
173
|
attack = Study[str](
|
|
@@ -15,6 +15,7 @@ from dreadnode.airt.compliance import (
|
|
|
15
15
|
tag_attack,
|
|
16
16
|
)
|
|
17
17
|
from dreadnode.airt.prompt import OBJECTIVE_SCORE_KEY, _evaluate_prompt
|
|
18
|
+
from dreadnode.core.meta import TrialCandidate
|
|
18
19
|
from dreadnode.core.scorer import Scorer
|
|
19
20
|
from dreadnode.core.transforms import Transform, TransformsLike
|
|
20
21
|
from dreadnode.generators.generator import Generator
|
|
@@ -142,6 +143,7 @@ def pair_attack(
|
|
|
142
143
|
llm_judge(
|
|
143
144
|
evaluator_model,
|
|
144
145
|
rubric,
|
|
146
|
+
input=TrialCandidate(),
|
|
145
147
|
min_score=1,
|
|
146
148
|
max_score=10,
|
|
147
149
|
)
|
|
@@ -157,6 +159,7 @@ def pair_attack(
|
|
|
157
159
|
target=target,
|
|
158
160
|
fitted_transforms=fitted_transforms,
|
|
159
161
|
scorer=prompt_judge,
|
|
162
|
+
include_input=True,
|
|
160
163
|
)
|
|
161
164
|
|
|
162
165
|
# Resolve model names for span attributes
|
|
@@ -18,6 +18,7 @@ from dreadnode.airt.compliance import (
|
|
|
18
18
|
tag_attack,
|
|
19
19
|
)
|
|
20
20
|
from dreadnode.airt.prompt import OBJECTIVE_SCORE_KEY, _evaluate_prompt
|
|
21
|
+
from dreadnode.core.meta import TrialCandidate
|
|
21
22
|
from dreadnode.core.scorer import Scorer
|
|
22
23
|
from dreadnode.core.transforms import Transform, TransformsLike
|
|
23
24
|
from dreadnode.generators.generator import Generator
|
|
@@ -170,6 +171,7 @@ def rainbow_attack(
|
|
|
170
171
|
llm_judge(
|
|
171
172
|
evaluator_model,
|
|
172
173
|
rubric,
|
|
174
|
+
input=TrialCandidate(),
|
|
173
175
|
min_score=1,
|
|
174
176
|
max_score=10,
|
|
175
177
|
)
|
|
@@ -185,6 +187,7 @@ def rainbow_attack(
|
|
|
185
187
|
target=target,
|
|
186
188
|
fitted_transforms=fitted_transforms,
|
|
187
189
|
scorer=prompt_judge,
|
|
190
|
+
include_input=True,
|
|
188
191
|
)
|
|
189
192
|
|
|
190
193
|
attack = Study[str](
|
|
@@ -18,6 +18,7 @@ from dreadnode.airt.compliance import (
|
|
|
18
18
|
tag_attack,
|
|
19
19
|
)
|
|
20
20
|
from dreadnode.airt.prompt import OBJECTIVE_SCORE_KEY, _evaluate_prompt
|
|
21
|
+
from dreadnode.core.meta import TrialCandidate
|
|
21
22
|
from dreadnode.core.scorer import Scorer
|
|
22
23
|
from dreadnode.core.transforms import Transform, TransformsLike
|
|
23
24
|
from dreadnode.generators.generator import GenerateParams, Generator, get_generator
|
|
@@ -165,6 +166,7 @@ def renellm_attack(
|
|
|
165
166
|
llm_judge(
|
|
166
167
|
evaluator_model,
|
|
167
168
|
rubric,
|
|
169
|
+
input=TrialCandidate(),
|
|
168
170
|
min_score=1,
|
|
169
171
|
max_score=10,
|
|
170
172
|
)
|
|
@@ -180,6 +182,7 @@ def renellm_attack(
|
|
|
180
182
|
target=target,
|
|
181
183
|
fitted_transforms=fitted_transforms,
|
|
182
184
|
scorer=prompt_judge,
|
|
185
|
+
include_input=True,
|
|
183
186
|
)
|
|
184
187
|
|
|
185
188
|
attack = Study[str](
|