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