dreadnode 2.0.26__tar.gz → 2.0.27__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.26 → dreadnode-2.0.27}/PKG-INFO +1 -1
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/api/client.py +6 -2
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/app.py +4 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/model_manager.py +34 -1
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/screens/models.py +145 -29
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/context_bar.py +21 -2
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/help_panel.py +16 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/getting-started/overview.md +2 -1
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/getting-started/quickstart.md +4 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/packaging/task_validation.py +103 -17
- {dreadnode-2.0.26 → dreadnode-2.0.27}/pyproject.toml +1 -1
- {dreadnode-2.0.26 → dreadnode-2.0.27}/.gitignore +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/LICENSE +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/README.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/__main__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/agents/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/agents/agent.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/agents/events.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/agents/exceptions.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/agents/format.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/agents/hooks.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/agents/judge.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/agents/mcp/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/agents/mcp/auth.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/agents/mcp/client.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/agents/mcp/config.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/agents/mcp/server.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/agents/process_judge.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/agents/reactions.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/agents/skills.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/agents/stopping.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/agents/subagent.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/agents/tool_resolution.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/agents/tools.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/agents/trajectory.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/adversarial_reasoning.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/advpromptier.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/alignment_faking.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/analogy_escalation.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/analytics/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/analytics/aggregator.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/analytics/classifier.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/analytics/compliance.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/analytics/engine.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/analytics/recommendations.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/analytics/types.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/aprt_progressive.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/assessment.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/attention_shifting.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/autodan_turbo.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/autoredteamer.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/beast.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/compliance/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/compliance/atlas.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/compliance/nist.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/compliance/owasp.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/compliance/owasp_agentic.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/compliance/saif.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/constants.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/cot_jailbreak.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/crescendo.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/data/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/data/assets/audio/adversarial_query.mp3 +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/data/assets/image/bomb.jpg +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/data/assets/image/meth.png +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/data/prompts/adversarial_benchmark_subset.csv +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/data/prompts/ai_safety.csv +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/data/rubrics/data_exfiltration.yaml +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/data/rubrics/goal_hijacking.yaml +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/data/rubrics/idor.yaml +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/data/rubrics/memory_poisoning.yaml +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/data/rubrics/privilege_escalation.yaml +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/data/rubrics/rce.yaml +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/data/rubrics/scope_creep.yaml +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/data/rubrics/tool_chaining.yaml +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/data/rubrics/tool_selection_safety.yaml +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/data/rubrics/unbounded_agency.yaml +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/data/rubrics/web_chatbot_security.yaml +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/data/templates/crescendo/variant_1.yaml +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/data/templates/crescendo/variant_2.yaml +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/data/templates/crescendo/variant_3.yaml +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/data/templates/crescendo/variant_4.yaml +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/data/templates/crescendo/variant_5.yaml +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/deep_inception.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/drattack.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/echo_chamber.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/events.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/genetic_persona.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/goat.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/goat_v2.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/gptfuzzer.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/humor_bypass.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/image.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/j2_meta.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/jbdistill.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/jbfuzz.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/lrm_autonomous.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/mapf.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/multimodal.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/nexus.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/pair.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/persona_hijack.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/prompt.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/quantization_safety.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/rainbow.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/refusal_aware.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/renellm.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/reporting/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/reporting/json_report.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/reporting/llm_summary.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/reporting/markdown.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/reward_hacking.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/salami_slicing.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/self_persuasion.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/siren.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/tap.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/templatefuzz.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/tmap_trajectory.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/trojail.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/airt/watermark_removal.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/api/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/api/models.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/airt.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/args.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/capability.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/dataset.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/environment.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/evaluation.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/inference_model.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/judge.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/main.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/model.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/optimize.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/runtime.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/sandbox.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/secret.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/session.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/shared.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/task.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/templates/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/templates/init/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/templates/init/challenge/Dockerfile +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/templates/init/docker-compose.yaml +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/templates/init/provision.sh +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/templates/init/solution.sh +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/templates/init/task-remote.yaml.tmpl +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/templates/init/task.yaml.tmpl +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/templates/init/teardown.sh +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/templates/init/verify.sh +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/train.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/cli/worlds.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/client/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/client/interactive.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/client/managed_client.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/client/models.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/client/runtime_client.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/client/transports.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/config.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/env.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/main.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/model_catalog.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/paths.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/print_mode.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/server/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/server/app.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/server/auth.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/server/capability_manager.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/server/model_resolution.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/server/prompt.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/server/prompt_registry.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/server/runtime_events.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/server/session_hydrator.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/server/session_persistence.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/server/turn_coordinator.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/server/utils.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/server/websocket.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/server/worker_manager.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/auth_flow.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/capabilities_manager.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/command_dispatcher.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/commands.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/connection.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/dreadnode.tcss +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/error_handler.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/model_variants.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/profile_manager.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/runtime_cache.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/screen_router.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/screens/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/screens/auth.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/screens/base.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/screens/capabilities.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/screens/capability_docs.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/screens/connection_error.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/screens/console.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/screens/environments.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/screens/evaluations.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/screens/model_picker.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/screens/raw_spans.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/screens/runtimes.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/screens/sandboxes.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/screens/secrets.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/screens/services.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/screens/sessions.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/screens/theme_showcase.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/screens/traces.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/screens/workspaces.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/sessions_manager.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/spans_reader.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/status_messages.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/theme.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/tool_format.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/turn_coordinator.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/turn_lifecycle.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/turn_reducer.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/turn_state_phase.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/update_check.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/agent_dialog.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/agent_suggester.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/composer.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/confirm_modal.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/conversation.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/flash.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/header_bar.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/human_prompt.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/mention_overlay.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/message_queue.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/new_messages_pill.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/overlay_mixin.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/permission_prompt.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/profile_dialog.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/prompt_info.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/rewind_picker.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/session_sidebar.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/skills_dialog.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/slash_overlay.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/status_bar.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/throbber.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/tool.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/tool_progress.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/tools_dialog.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/welcome.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/widgets/whoami.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/app/tui/wire_events.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/MAINTAINING.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/agents/dreadnode.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/capability.yaml +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/SKILL.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/capability-improvement.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/methodology-grounding.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/prior-art-audit.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/promoting-capabilities.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/quality-bar.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/INDEX.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/agents.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/dependencies-and-checks.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/env-vars.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/events.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/flags.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/hooks.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/installing.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/manifest.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/mcp-servers.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/overview.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/policies.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/publishing.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/quickstart.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/skills.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/tools.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/workers-reference.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/workers.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/capabilities/writing-skills.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/guides/capability-optimization-loop.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/sdk/agents.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/sdk/capabilities.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references/tui/default-tools.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/references-and-depth.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/runtime-default-capability.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/SKILL.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/INDEX.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/airt.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/capability.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/dataset.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/env.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/evaluation.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/inference-model.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/main.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/model.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/optimize.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/overview.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/runtime.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/sandbox.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/secret.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/task.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/train.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/cli/worlds.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/getting-started/authentication.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/SKILL.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/INDEX.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/capabilities/installing.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/capabilities/overview.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/getting-started/authentication.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/chat-models.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/credits.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/organizations.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/overview.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/projects.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/secrets.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/settings.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/users.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/platform/workspaces.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/configuration.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/managing.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/manifest-reference.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/overview.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/quickstart.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/runtimes/serve.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/sandboxes/environment-lifecycle.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/sandboxes/inspecting.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-concepts/references/sandboxes/overview.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/getting-started/SKILL.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/dreadnode/skills/research-capabilities/SKILL.md +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/self-improvement/.gitignore +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/self-improvement/capability.yaml +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/self-improvement/hooks/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/self-improvement/hooks/observer.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/classifier.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/reflector_goal.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/self-improvement/self_improvement_lib/skill_io.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/self-improvement/skills-promoted/.gitkeep +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/self-improvement/skills-proposed/.gitkeep +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/self-improvement/tools/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/self-improvement/tools/reflector.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/builtin_capabilities/self-improvement/tools/skill_stats.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/capabilities/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/capabilities/capability.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/capabilities/flags.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/capabilities/install.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/capabilities/loader.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/capabilities/sync.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/capabilities/tool_rules.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/capabilities/types.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/capabilities/worker.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/capabilities/worker_runner.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/conditions.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/discovery.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/environment.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/exceptions.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/execution.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/hook.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/judge.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/load.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/log.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/meta/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/meta/config.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/meta/context.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/meta/hydrate.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/meta/introspect.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/metric.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/object.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/scorer.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/serialization.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/stopping.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/task.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/templating.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/transforms.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/types/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/types/audio.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/types/base.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/types/common.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/types/image.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/types/object_3d.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/types/table.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/types/text.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/types/video.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/core/util.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/datasets/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/datasets/dataset.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/datasets/hf.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/datasets/local.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/evaluations/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/evaluations/console.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/evaluations/evaluation.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/evaluations/events.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/evaluations/format.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/evaluations/result.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/evaluations/sample.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/generators/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/generators/caching.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/generators/chat.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/generators/data.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/generators/exceptions.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/generators/generator/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/generators/generator/base.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/generators/generator/http.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/generators/generator/litellm_.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/generators/generator/transformers_.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/generators/generator/vllm_.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/generators/message.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/generators/models.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/generators/parsing.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/generators/tokenizer/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/generators/tokenizer/base.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/generators/tokenizer/transformers_.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/generators/utils.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/judges/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/judges/outcome.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/judges/trajectory.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/judges/trajectory_tools.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/models/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/models/hf.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/models/local.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/models/model.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/optimization/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/optimization/adapters/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/optimization/adapters/_env_eval.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/optimization/adapters/agent.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/optimization/adapters/env.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/optimization/adapters/runtime.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/optimization/adapters/stack.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/optimization/api.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/optimization/backends/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/optimization/backends/base.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/optimization/backends/gepa.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/optimization/collectors.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/optimization/config.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/optimization/console.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/optimization/events.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/optimization/format.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/optimization/jobs.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/optimization/result.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/optimization/sampler.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/optimization/sampling.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/optimization/search.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/optimization/stopping.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/optimization/study.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/optimization/trial.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/packaging/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/packaging/loader.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/packaging/manifest.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/packaging/oci.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/packaging/package.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/policies/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/policies/guard.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/policies/rubrics/process/default.yaml +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/py.typed +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/samplers/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/samplers/boundary.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/samplers/fuzzing.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/samplers/graph.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/samplers/grid.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/samplers/image.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/samplers/mapelites.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/samplers/optuna.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/samplers/random.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/samplers/registry.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/samplers/strategy.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/advanced_jailbreak_detection.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/agent_security.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/agentic.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/agentic_workflow.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/attack_outcome.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/classification.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/consistency.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/contains.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/cosine_sim.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/credentials.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/crucible.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/documentation_security.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/exfiltration_detection.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/format.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/harm.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/ide_security.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/image.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/json.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/judge.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/judge_ensemble.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/length.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/lexical.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/mcp_security.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/memorization.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/multi_agent_security.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/pii.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/prompt_leak.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/readability.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/reasoning_security.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/sentiment.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/similarity.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/structural_detection.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/scorers/supply_chain_detection.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/storage/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/storage/providers.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/storage/session_store.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/storage/storage.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tools/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tools/_ripgrep.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tools/apply_patch.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tools/dreadnode_cli.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tools/editing.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tools/execute.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tools/fetch.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tools/glob.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tools/grep.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tools/interaction.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tools/ls.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tools/memory.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tools/read.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tools/report.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tools/task.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tools/think.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tools/todo.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tools/trajectory_search.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tools/web_extract.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tools/web_search.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tools/write.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tracing/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tracing/constants.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tracing/convert.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tracing/exporter.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tracing/exporters.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tracing/span.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tracing/spans.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/tracing/trace_converter.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/_progress.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/base.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/dpo.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/env_rollouts.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/etl/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/etl/_common.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/etl/rl.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/etl/sft.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/etl/worlds.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/events.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/grpo.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/jobs.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/models.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/ppo.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/prime.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/ray/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/ray/async_trainer.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/ray/config.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/ray/coordinator.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/ray/distributed.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/ray/dpo.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/ray/experience.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/ray/fsdp2_learner.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/ray/inference.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/ray/learner.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/ray/multi_turn.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/ray/ppo.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/ray/reward_model.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/ray/rollout_env.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/ray/rollout_worker.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/ray/sft.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/ray/trainer.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/recipes.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/rewards/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/rewards/aggregator.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/rewards/functions.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/rewards/scorer_bridge.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/rewards/shaping.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/rewards/types.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/rollouts/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/rollouts/adapters.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/rollouts/agent_rollout.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/rollouts/orchestrator.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/rollouts/types.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/rollouts/worlds.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/serving/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/serving/vllm_client.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/sft.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/tinker/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/tinker/config.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/tinker/data.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/tinker/renderer.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/tinker/rl.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/tinker/trainer.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/tinker_sft.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/training/utils.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/__init__.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/advanced_jailbreak.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/adversarial_suffix.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/agent_skill.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/agentic_workflow.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/audio.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/backdoor_finetune.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/browser_agent_attacks.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/cipher.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/competitive_parity.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/constitutional.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/document.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/documentation_poison.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/encoding.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/exfiltration.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/flip_attack.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/guardrail_bypass.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/ide_injection.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/image.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/injection.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/json_tools.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/language.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/logic_bomb.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/mcp_attacks.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/multi_agent_attacks.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/multimodal_attacks.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/persuasion.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/perturbation.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/pii_extraction.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/pythonic_tools.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/rag_poisoning.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/reasoning_attacks.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/refine.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/response_steering.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/structural_exploits.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/stylistic.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/substitution.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/supply_chain.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/swap.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/system_prompt_extraction.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/text.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/video.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/transforms/xml_tools.py +0 -0
- {dreadnode-2.0.26 → dreadnode-2.0.27}/dreadnode/version.py +0 -0
|
@@ -363,9 +363,13 @@ class ApiClient:
|
|
|
363
363
|
response = self.request("GET", "/user/preferences", params=params)
|
|
364
364
|
return t.cast("dict[str, t.Any]", response.json())
|
|
365
365
|
|
|
366
|
-
def provision_inference_key(self, org_key: str) -> dict[str, t.Any]:
|
|
366
|
+
def provision_inference_key(self, org_key: str, client_id: str) -> dict[str, t.Any]:
|
|
367
367
|
"""POST /api/v1/org/{org}/inference/keys - Provision a litellm virtual key."""
|
|
368
|
-
response = self.request(
|
|
368
|
+
response = self.request(
|
|
369
|
+
"POST",
|
|
370
|
+
f"/org/{org_key}/inference/keys",
|
|
371
|
+
json_data={"client_id": client_id},
|
|
372
|
+
)
|
|
369
373
|
return t.cast("dict[str, t.Any]", response.json())
|
|
370
374
|
|
|
371
375
|
# =========================================================================
|
|
@@ -257,6 +257,7 @@ class _AppModelUiHost:
|
|
|
257
257
|
platform_models: list[dict[str, t.Any]],
|
|
258
258
|
byok_models: list[dict[str, t.Any]],
|
|
259
259
|
current_model: str,
|
|
260
|
+
inference_credits_per_dollar: int | None,
|
|
260
261
|
access_restricted: bool,
|
|
261
262
|
search_models: t.Callable[..., t.Any],
|
|
262
263
|
on_selected: t.Callable[[str | None], None],
|
|
@@ -268,6 +269,7 @@ class _AppModelUiHost:
|
|
|
268
269
|
platform_models=platform_models,
|
|
269
270
|
byok_models=byok_models,
|
|
270
271
|
current_model=current_model,
|
|
272
|
+
inference_credits_per_dollar=inference_credits_per_dollar,
|
|
271
273
|
access_restricted=access_restricted,
|
|
272
274
|
search_models=search_models,
|
|
273
275
|
),
|
|
@@ -280,6 +282,7 @@ class _AppModelUiHost:
|
|
|
280
282
|
platform_models: list[dict[str, t.Any]],
|
|
281
283
|
byok_models: list[dict[str, t.Any]],
|
|
282
284
|
current_model: str,
|
|
285
|
+
inference_credits_per_dollar: int | None,
|
|
283
286
|
access_restricted: bool,
|
|
284
287
|
) -> None:
|
|
285
288
|
from dreadnode.app.tui.screens import ModelBrowserScreen
|
|
@@ -291,6 +294,7 @@ class _AppModelUiHost:
|
|
|
291
294
|
platform_models=platform_models,
|
|
292
295
|
byok_models=byok_models,
|
|
293
296
|
current_model=current_model,
|
|
297
|
+
inference_credits_per_dollar=inference_credits_per_dollar,
|
|
294
298
|
access_restricted=access_restricted,
|
|
295
299
|
)
|
|
296
300
|
break
|
|
@@ -9,6 +9,7 @@ import typing as t
|
|
|
9
9
|
from dataclasses import dataclass, field
|
|
10
10
|
from datetime import UTC, datetime, timedelta
|
|
11
11
|
from pathlib import Path
|
|
12
|
+
from uuid import uuid4
|
|
12
13
|
|
|
13
14
|
import httpx
|
|
14
15
|
from loguru import logger
|
|
@@ -25,6 +26,7 @@ LITELLM_REFRESH_WINDOW = timedelta(minutes=5)
|
|
|
25
26
|
PROXY_MODELS_CACHE_FILE = Path.home() / ".dreadnode" / "proxy-models.json"
|
|
26
27
|
MODEL_BROWSER_FEATURED_LIMIT = 12
|
|
27
28
|
MODEL_BROWSER_SEARCH_LIMIT = 50
|
|
29
|
+
DEFAULT_INFERENCE_CREDITS_PER_DOLLAR = 1000
|
|
28
30
|
|
|
29
31
|
|
|
30
32
|
@dataclass(slots=True)
|
|
@@ -32,6 +34,7 @@ class ModelCatalogState:
|
|
|
32
34
|
platform_models: list[dict[str, t.Any]] = field(default_factory=list)
|
|
33
35
|
user_model_ids: list[str] = field(default_factory=list)
|
|
34
36
|
preference_platform_model_ids: list[str] = field(default_factory=list)
|
|
37
|
+
inference_credits_per_dollar: int | None = None
|
|
35
38
|
access_restricted: bool = False
|
|
36
39
|
proxy_model_ids_synced: bool = False
|
|
37
40
|
litellm_key_expires_at: datetime | None = None
|
|
@@ -72,6 +75,7 @@ class ModelUiHost(t.Protocol):
|
|
|
72
75
|
platform_models: list[dict[str, t.Any]],
|
|
73
76
|
byok_models: list[dict[str, t.Any]],
|
|
74
77
|
current_model: str,
|
|
78
|
+
inference_credits_per_dollar: int | None,
|
|
75
79
|
access_restricted: bool,
|
|
76
80
|
search_models: t.Callable[..., t.Any],
|
|
77
81
|
on_selected: t.Callable[[str | None], None],
|
|
@@ -83,6 +87,7 @@ class ModelUiHost(t.Protocol):
|
|
|
83
87
|
platform_models: list[dict[str, t.Any]],
|
|
84
88
|
byok_models: list[dict[str, t.Any]],
|
|
85
89
|
current_model: str,
|
|
90
|
+
inference_credits_per_dollar: int | None,
|
|
86
91
|
access_restricted: bool,
|
|
87
92
|
) -> None: ...
|
|
88
93
|
|
|
@@ -122,6 +127,7 @@ class ModelManager:
|
|
|
122
127
|
self._runner = runner
|
|
123
128
|
self._notifier = notifier
|
|
124
129
|
self._actions = actions
|
|
130
|
+
self._tui_client_id = uuid4().hex
|
|
125
131
|
|
|
126
132
|
def open_model_picker(self) -> None:
|
|
127
133
|
"""Show the inline model picker overlay."""
|
|
@@ -152,6 +158,7 @@ class ModelManager:
|
|
|
152
158
|
platform_models=list(self._state.platform_models),
|
|
153
159
|
byok_models=self.browser_seed_models(),
|
|
154
160
|
current_model=self._context.current_model(),
|
|
161
|
+
inference_credits_per_dollar=self._state.inference_credits_per_dollar,
|
|
155
162
|
access_restricted=self._state.access_restricted,
|
|
156
163
|
search_models=self.search_model_browser_models,
|
|
157
164
|
on_selected=self.apply_model_selection,
|
|
@@ -253,6 +260,7 @@ class ModelManager:
|
|
|
253
260
|
platform_models=list(self._state.platform_models),
|
|
254
261
|
byok_models=self.browser_seed_models(),
|
|
255
262
|
current_model=self._context.current_model(),
|
|
263
|
+
inference_credits_per_dollar=self._state.inference_credits_per_dollar,
|
|
256
264
|
access_restricted=self._state.access_restricted,
|
|
257
265
|
)
|
|
258
266
|
|
|
@@ -281,12 +289,25 @@ class ModelManager:
|
|
|
281
289
|
self._state.platform_models = []
|
|
282
290
|
self._state.user_model_ids = []
|
|
283
291
|
self._state.preference_platform_model_ids = []
|
|
292
|
+
self._state.inference_credits_per_dollar = None
|
|
284
293
|
self._state.access_restricted = False
|
|
285
294
|
self._state.proxy_model_ids_synced = False
|
|
286
295
|
self._state.litellm_key_expires_at = None
|
|
287
296
|
os.environ.pop(DREADNODE_LLM_BASE_ENV, None)
|
|
288
297
|
os.environ.pop(DREADNODE_LLM_API_KEY_ENV, None)
|
|
289
298
|
|
|
299
|
+
@staticmethod
|
|
300
|
+
def parse_inference_credits_per_dollar(value: t.Any) -> int | None:
|
|
301
|
+
if value is None:
|
|
302
|
+
return DEFAULT_INFERENCE_CREDITS_PER_DOLLAR
|
|
303
|
+
if isinstance(value, bool):
|
|
304
|
+
return None
|
|
305
|
+
if isinstance(value, int) and value > 0:
|
|
306
|
+
return value
|
|
307
|
+
if isinstance(value, float) and value > 0:
|
|
308
|
+
return int(value)
|
|
309
|
+
return None
|
|
310
|
+
|
|
290
311
|
@staticmethod
|
|
291
312
|
def normalize_platform_model_ids(model_ids: list[str] | None) -> list[str]:
|
|
292
313
|
if not model_ids:
|
|
@@ -355,8 +376,13 @@ class ModelManager:
|
|
|
355
376
|
if name:
|
|
356
377
|
result["name"] = name
|
|
357
378
|
for extra_field in (
|
|
379
|
+
"order",
|
|
358
380
|
"cost",
|
|
359
381
|
"limits",
|
|
382
|
+
"cost_input",
|
|
383
|
+
"cost_output",
|
|
384
|
+
"context_window",
|
|
385
|
+
"max_output",
|
|
360
386
|
"capabilities",
|
|
361
387
|
"modalities",
|
|
362
388
|
"knowledge",
|
|
@@ -744,6 +770,9 @@ class ModelManager:
|
|
|
744
770
|
self._state.preference_platform_model_ids = self.normalize_platform_model_ids(
|
|
745
771
|
platform_model_ids
|
|
746
772
|
)
|
|
773
|
+
self._state.inference_credits_per_dollar = self.parse_inference_credits_per_dollar(
|
|
774
|
+
preferences.get("inference_credits_per_dollar")
|
|
775
|
+
)
|
|
747
776
|
self._state.access_restricted = bool(preferences.get("access_restricted"))
|
|
748
777
|
self.apply_restricted_current_model_fallback()
|
|
749
778
|
if not self._state.platform_models:
|
|
@@ -787,7 +816,11 @@ class ModelManager:
|
|
|
787
816
|
return None
|
|
788
817
|
try:
|
|
789
818
|
t0 = time.monotonic()
|
|
790
|
-
result = await asyncio.to_thread(
|
|
819
|
+
result = await asyncio.to_thread(
|
|
820
|
+
api.provision_inference_key,
|
|
821
|
+
org,
|
|
822
|
+
self._tui_client_id,
|
|
823
|
+
)
|
|
791
824
|
logger.debug(
|
|
792
825
|
"LiteLLM key provisioned | elapsed={:.0f}ms",
|
|
793
826
|
(time.monotonic() - t0) * 1000,
|
|
@@ -63,6 +63,7 @@ class ModelEntry:
|
|
|
63
63
|
knowledge: str | None = None
|
|
64
64
|
release_date: str | None = None
|
|
65
65
|
open_weights: bool | None = None
|
|
66
|
+
order: int | None = None
|
|
66
67
|
|
|
67
68
|
|
|
68
69
|
@dataclass(slots=True, frozen=True)
|
|
@@ -129,9 +130,48 @@ def _format_context(value: int | None) -> str:
|
|
|
129
130
|
return _format_compact_int(value)
|
|
130
131
|
|
|
131
132
|
|
|
132
|
-
def
|
|
133
|
+
def _format_compact_number(value: float) -> str:
|
|
134
|
+
rounded_value = round(value, 6)
|
|
135
|
+
if abs(rounded_value) >= 1_000_000:
|
|
136
|
+
return f"{rounded_value / 1_000_000:g}m"
|
|
137
|
+
if abs(rounded_value) >= 1_000:
|
|
138
|
+
return f"{rounded_value / 1_000:g}k"
|
|
139
|
+
if rounded_value.is_integer():
|
|
140
|
+
return str(int(rounded_value))
|
|
141
|
+
return f"{rounded_value:g}"
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def _format_price(
|
|
145
|
+
input_cost: float | None,
|
|
146
|
+
output_cost: float | None,
|
|
147
|
+
*,
|
|
148
|
+
source: t.Literal["dreadnode", "byok"],
|
|
149
|
+
inference_credits_per_dollar: float | None,
|
|
150
|
+
) -> str:
|
|
133
151
|
if input_cost is None and output_cost is None:
|
|
134
152
|
return "-"
|
|
153
|
+
|
|
154
|
+
if source == "dreadnode":
|
|
155
|
+
if not (
|
|
156
|
+
isinstance(inference_credits_per_dollar, int | float)
|
|
157
|
+
and inference_credits_per_dollar > 0
|
|
158
|
+
):
|
|
159
|
+
return "-"
|
|
160
|
+
input_credits = (
|
|
161
|
+
_format_compact_number(input_cost * inference_credits_per_dollar)
|
|
162
|
+
if input_cost is not None
|
|
163
|
+
else None
|
|
164
|
+
)
|
|
165
|
+
output_credits = (
|
|
166
|
+
_format_compact_number(output_cost * inference_credits_per_dollar)
|
|
167
|
+
if output_cost is not None
|
|
168
|
+
else None
|
|
169
|
+
)
|
|
170
|
+
if input_credits is not None and output_credits is not None:
|
|
171
|
+
return f"{input_credits}/{output_credits} cr"
|
|
172
|
+
value = input_credits if input_credits is not None else output_credits
|
|
173
|
+
return f"{value} cr"
|
|
174
|
+
|
|
135
175
|
if input_cost is not None and output_cost is not None:
|
|
136
176
|
return f"${input_cost:g}/${output_cost:g}"
|
|
137
177
|
value = input_cost if input_cost is not None else output_cost
|
|
@@ -146,27 +186,57 @@ def _format_open_weights(value: bool | None) -> str:
|
|
|
146
186
|
return "-"
|
|
147
187
|
|
|
148
188
|
|
|
189
|
+
def _parse_float_value(raw: t.Any) -> float | None:
|
|
190
|
+
if isinstance(raw, bool):
|
|
191
|
+
return None
|
|
192
|
+
if isinstance(raw, int | float):
|
|
193
|
+
return float(raw)
|
|
194
|
+
return None
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def _parse_int_value(raw: t.Any) -> int | None:
|
|
198
|
+
if isinstance(raw, bool):
|
|
199
|
+
return None
|
|
200
|
+
if isinstance(raw, int | float):
|
|
201
|
+
return int(raw)
|
|
202
|
+
return None
|
|
203
|
+
|
|
204
|
+
|
|
149
205
|
def _parse_cost_fields(entry: dict[str, t.Any]) -> tuple[float | None, float | None]:
|
|
150
206
|
cost = entry.get("cost")
|
|
151
|
-
if
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
207
|
+
input_cost = cost.get("input") if isinstance(cost, dict) else None
|
|
208
|
+
output_cost = cost.get("output") if isinstance(cost, dict) else None
|
|
209
|
+
|
|
210
|
+
parsed_input_cost = _parse_float_value(input_cost)
|
|
211
|
+
if parsed_input_cost is None:
|
|
212
|
+
parsed_input_cost = _parse_float_value(entry.get("cost_input"))
|
|
213
|
+
|
|
214
|
+
parsed_output_cost = _parse_float_value(output_cost)
|
|
215
|
+
if parsed_output_cost is None:
|
|
216
|
+
parsed_output_cost = _parse_float_value(entry.get("cost_output"))
|
|
217
|
+
|
|
155
218
|
return (
|
|
156
|
-
|
|
157
|
-
|
|
219
|
+
parsed_input_cost,
|
|
220
|
+
parsed_output_cost,
|
|
158
221
|
)
|
|
159
222
|
|
|
160
223
|
|
|
161
224
|
def _parse_limit_fields(entry: dict[str, t.Any]) -> tuple[int | None, int | None]:
|
|
162
225
|
limits = entry.get("limits")
|
|
163
|
-
if
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
226
|
+
context_window = limits.get("context") if isinstance(limits, dict) else None
|
|
227
|
+
max_output = limits.get("output") if isinstance(limits, dict) else None
|
|
228
|
+
|
|
229
|
+
parsed_context_window = _parse_int_value(context_window)
|
|
230
|
+
if parsed_context_window is None:
|
|
231
|
+
parsed_context_window = _parse_int_value(entry.get("context_window"))
|
|
232
|
+
|
|
233
|
+
parsed_max_output = _parse_int_value(max_output)
|
|
234
|
+
if parsed_max_output is None:
|
|
235
|
+
parsed_max_output = _parse_int_value(entry.get("max_output"))
|
|
236
|
+
|
|
167
237
|
return (
|
|
168
|
-
|
|
169
|
-
|
|
238
|
+
parsed_context_window,
|
|
239
|
+
parsed_max_output,
|
|
170
240
|
)
|
|
171
241
|
|
|
172
242
|
|
|
@@ -373,6 +443,19 @@ def _build_entries(
|
|
|
373
443
|
hosted: dict[str, ModelEntry] = {}
|
|
374
444
|
byok: dict[str, ModelEntry] = {}
|
|
375
445
|
|
|
446
|
+
def parse_order(value: object) -> int | None:
|
|
447
|
+
if isinstance(value, bool):
|
|
448
|
+
return None
|
|
449
|
+
if isinstance(value, int) and value >= 1:
|
|
450
|
+
return value
|
|
451
|
+
if isinstance(value, str) and value.strip():
|
|
452
|
+
try:
|
|
453
|
+
parsed = int(value)
|
|
454
|
+
except ValueError:
|
|
455
|
+
return None
|
|
456
|
+
return parsed if parsed >= 1 else None
|
|
457
|
+
return None
|
|
458
|
+
|
|
376
459
|
for entry in platform_models:
|
|
377
460
|
if not isinstance(entry, dict):
|
|
378
461
|
continue
|
|
@@ -411,6 +494,7 @@ def _build_entries(
|
|
|
411
494
|
open_weights=entry.get("open_weights")
|
|
412
495
|
if isinstance(entry.get("open_weights"), bool)
|
|
413
496
|
else None,
|
|
497
|
+
order=parse_order(entry.get("order")),
|
|
414
498
|
)
|
|
415
499
|
|
|
416
500
|
for entry in byok_models:
|
|
@@ -469,18 +553,19 @@ def _build_entries(
|
|
|
469
553
|
source="dreadnode" if current_model.startswith("dn/") else "byok",
|
|
470
554
|
)
|
|
471
555
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
entry.model_id.lower(),
|
|
478
|
-
)
|
|
479
|
-
|
|
480
|
-
return sorted([*hosted.values(), *byok.values()], key=sort_key)
|
|
556
|
+
ordered_hosted = sorted(
|
|
557
|
+
enumerate(hosted.values()),
|
|
558
|
+
key=lambda item: (item[1].order is None, item[1].order or 0, item[0]),
|
|
559
|
+
)
|
|
560
|
+
return [*(entry for _index, entry in ordered_hosted), *byok.values()]
|
|
481
561
|
|
|
482
562
|
|
|
483
|
-
def _matches_text(
|
|
563
|
+
def _matches_text(
|
|
564
|
+
entry: ModelEntry,
|
|
565
|
+
query: str,
|
|
566
|
+
*,
|
|
567
|
+
inference_credits_per_dollar: float | None,
|
|
568
|
+
) -> bool:
|
|
484
569
|
if not query:
|
|
485
570
|
return True
|
|
486
571
|
haystack = " ".join(
|
|
@@ -492,7 +577,12 @@ def _matches_text(entry: ModelEntry, query: str) -> bool:
|
|
|
492
577
|
_source_label(entry.source),
|
|
493
578
|
entry.status or "",
|
|
494
579
|
_format_context(entry.context_window),
|
|
495
|
-
_format_price(
|
|
580
|
+
_format_price(
|
|
581
|
+
entry.cost_input,
|
|
582
|
+
entry.cost_output,
|
|
583
|
+
source=entry.source,
|
|
584
|
+
inference_credits_per_dollar=inference_credits_per_dollar,
|
|
585
|
+
),
|
|
496
586
|
_format_open_weights(entry.open_weights),
|
|
497
587
|
entry.knowledge or "",
|
|
498
588
|
entry.release_date or "",
|
|
@@ -505,7 +595,12 @@ def _matches_text(entry: ModelEntry, query: str) -> bool:
|
|
|
505
595
|
return query.lower() in haystack
|
|
506
596
|
|
|
507
597
|
|
|
508
|
-
def _filter_entries(
|
|
598
|
+
def _filter_entries(
|
|
599
|
+
entries: list[ModelEntry],
|
|
600
|
+
search: ModelSearch | str,
|
|
601
|
+
*,
|
|
602
|
+
inference_credits_per_dollar: float | None = None,
|
|
603
|
+
) -> list[ModelEntry]:
|
|
509
604
|
"""Filter model entries by free text and structured metadata filters."""
|
|
510
605
|
normalized = _parse_search_query(search) if isinstance(search, str) else search
|
|
511
606
|
|
|
@@ -534,7 +629,11 @@ def _filter_entries(entries: list[ModelEntry], search: ModelSearch | str) -> lis
|
|
|
534
629
|
continue
|
|
535
630
|
if normalized.max_price is not None and (price is None or price > normalized.max_price):
|
|
536
631
|
continue
|
|
537
|
-
if not _matches_text(
|
|
632
|
+
if not _matches_text(
|
|
633
|
+
entry,
|
|
634
|
+
normalized.text,
|
|
635
|
+
inference_credits_per_dollar=inference_credits_per_dollar,
|
|
636
|
+
):
|
|
538
637
|
continue
|
|
539
638
|
results.append(entry)
|
|
540
639
|
return results
|
|
@@ -563,6 +662,7 @@ class ModelBrowserScreen(Screen[str | None]):
|
|
|
563
662
|
platform_models: list[dict[str, t.Any]],
|
|
564
663
|
byok_models: list[dict[str, t.Any]],
|
|
565
664
|
current_model: str,
|
|
665
|
+
inference_credits_per_dollar: float | None = None,
|
|
566
666
|
access_restricted: bool = False,
|
|
567
667
|
search_models: SearchModelsCallback | None = None,
|
|
568
668
|
**kwargs: t.Any,
|
|
@@ -572,6 +672,7 @@ class ModelBrowserScreen(Screen[str | None]):
|
|
|
572
672
|
self._seed_byok_models = list(byok_models)
|
|
573
673
|
self._catalog_byok_models = list(byok_models)
|
|
574
674
|
self._current_model = current_model
|
|
675
|
+
self._inference_credits_per_dollar = inference_credits_per_dollar
|
|
575
676
|
self._access_restricted = access_restricted
|
|
576
677
|
self._search_models = search_models
|
|
577
678
|
self._search_loading = False
|
|
@@ -631,12 +732,14 @@ class ModelBrowserScreen(Screen[str | None]):
|
|
|
631
732
|
platform_models: list[dict[str, t.Any]],
|
|
632
733
|
byok_models: list[dict[str, t.Any]],
|
|
633
734
|
current_model: str,
|
|
735
|
+
inference_credits_per_dollar: float | None = None,
|
|
634
736
|
access_restricted: bool,
|
|
635
737
|
) -> None:
|
|
636
738
|
"""Refresh the browser contents from app state."""
|
|
637
739
|
self._platform_models = list(platform_models)
|
|
638
740
|
self._seed_byok_models = list(byok_models)
|
|
639
741
|
self._current_model = current_model
|
|
742
|
+
self._inference_credits_per_dollar = inference_credits_per_dollar
|
|
640
743
|
self._access_restricted = access_restricted
|
|
641
744
|
self._rebuild_entries()
|
|
642
745
|
if not self._search_query:
|
|
@@ -842,7 +945,11 @@ class ModelBrowserScreen(Screen[str | None]):
|
|
|
842
945
|
self.query_one("#models-header", Static).update(text)
|
|
843
946
|
|
|
844
947
|
def _render_table(self) -> None:
|
|
845
|
-
self._visible = _filter_entries(
|
|
948
|
+
self._visible = _filter_entries(
|
|
949
|
+
self._entries,
|
|
950
|
+
_parse_search_query(self._search_query),
|
|
951
|
+
inference_credits_per_dollar=self._inference_credits_per_dollar,
|
|
952
|
+
)
|
|
846
953
|
self._cursor = min(self._cursor, max(0, len(self._visible) - 1))
|
|
847
954
|
self._render_query_bar()
|
|
848
955
|
table = self.query_one("#models-table", DataTable)
|
|
@@ -865,7 +972,12 @@ class ModelBrowserScreen(Screen[str | None]):
|
|
|
865
972
|
entry.provider or "-",
|
|
866
973
|
source,
|
|
867
974
|
_format_context(entry.context_window),
|
|
868
|
-
_format_price(
|
|
975
|
+
_format_price(
|
|
976
|
+
entry.cost_input,
|
|
977
|
+
entry.cost_output,
|
|
978
|
+
source=entry.source,
|
|
979
|
+
inference_credits_per_dollar=self._inference_credits_per_dollar,
|
|
980
|
+
),
|
|
869
981
|
_format_open_weights(entry.open_weights),
|
|
870
982
|
entry.model_id,
|
|
871
983
|
key=entry.model_id,
|
|
@@ -950,7 +1062,11 @@ class ModelBrowserScreen(Screen[str | None]):
|
|
|
950
1062
|
self._catalog_byok_models = list(results)
|
|
951
1063
|
self._rebuild_entries()
|
|
952
1064
|
self._cursor = self._current_index(
|
|
953
|
-
_filter_entries(
|
|
1065
|
+
_filter_entries(
|
|
1066
|
+
self._entries,
|
|
1067
|
+
_parse_search_query(self._search_query),
|
|
1068
|
+
inference_credits_per_dollar=self._inference_credits_per_dollar,
|
|
1069
|
+
)
|
|
954
1070
|
)
|
|
955
1071
|
if self.is_mounted:
|
|
956
1072
|
self._render_all()
|
|
@@ -5,7 +5,7 @@ SessionContextBar (Zone 1, 2 lines):
|
|
|
5
5
|
Line 2: ^A agent ^K model, ^⇧K reasoning
|
|
6
6
|
|
|
7
7
|
PageStatus (Zone 3, 1 line):
|
|
8
|
-
|
|
8
|
+
ctx 53.4k/200k tok · ⚒ 12 · usage $0.34 · ? help
|
|
9
9
|
|
|
10
10
|
The token gauge shows ``last_input_tokens / model_max_tokens`` — i.e., the
|
|
11
11
|
size of the prompt the model just saw against the model's context window.
|
|
@@ -18,6 +18,13 @@ The ``⚒`` and ``$X.XX`` segments only render when their values are known
|
|
|
18
18
|
and non-zero; on a session with at least one generation that lacked a cost
|
|
19
19
|
rate the dollar segment is suppressed entirely (matching the backend's
|
|
20
20
|
null-propagation for ``total_cost_usd``) — partial sums are misleading.
|
|
21
|
+
|
|
22
|
+
The ``ctx`` prefix labels the token gauge as a context-window meter (not a
|
|
23
|
+
quota); the ``usage`` prefix labels the dollar figure as cumulative cost
|
|
24
|
+
for this session only (not balance, not account-wide spend). The dollar
|
|
25
|
+
segment also carries an OSC 8 hyperlink to the public pricing docs so a
|
|
26
|
+
confused user can resolve the unit mismatch with one click in any modern
|
|
27
|
+
terminal — terminals without OSC 8 support simply render plain text.
|
|
21
28
|
"""
|
|
22
29
|
|
|
23
30
|
from __future__ import annotations
|
|
@@ -181,6 +188,13 @@ class ContextBar(SessionContextBar):
|
|
|
181
188
|
|
|
182
189
|
_ISSUE_DISPLAY_SECONDS = 60
|
|
183
190
|
|
|
191
|
+
# Public docs page that explains credits, the USD-to-credits rate, what
|
|
192
|
+
# consumes credits, and how the usage-cost figure relates to the org
|
|
193
|
+
# balance. Hard-coded by design: the TUI ships independently of docs and a
|
|
194
|
+
# config lookup would just add a network hop for a value that almost never
|
|
195
|
+
# changes. If this URL moves, the previous one should redirect.
|
|
196
|
+
PRICING_DOCS_URL = "https://docs.dreadnode.io/platform/credits/"
|
|
197
|
+
|
|
184
198
|
|
|
185
199
|
class PageStatus(Static):
|
|
186
200
|
"""Zone 3 — single-line page status below the composer.
|
|
@@ -232,6 +246,7 @@ class PageStatus(Static):
|
|
|
232
246
|
right = Text(no_wrap=True)
|
|
233
247
|
if self.last_input_tokens > 0:
|
|
234
248
|
limit = self.model_max_tokens if self.model_max_tokens > 0 else None
|
|
249
|
+
right.append("ctx ", style=FG_FAINTEST)
|
|
235
250
|
right.append_text(render_tokens(self.last_input_tokens, limit))
|
|
236
251
|
right.append(" · ", style=FG_FAINTEST)
|
|
237
252
|
if self.tool_call_count > 0:
|
|
@@ -239,7 +254,11 @@ class PageStatus(Static):
|
|
|
239
254
|
right.append(str(self.tool_call_count), style=FG_MUTED)
|
|
240
255
|
right.append(" · ", style=FG_FAINTEST)
|
|
241
256
|
if not self.cost_unknown and self.cost_usd > 0:
|
|
242
|
-
right.append(
|
|
257
|
+
right.append("usage ", style=FG_FAINTEST)
|
|
258
|
+
right.append(
|
|
259
|
+
_format_cost_usd(self.cost_usd),
|
|
260
|
+
style=f"{FG_MUTED} link {PRICING_DOCS_URL}",
|
|
261
|
+
)
|
|
243
262
|
right.append(" · ", style=FG_FAINTEST)
|
|
244
263
|
right.append("? help", style=FG_FAINTEST)
|
|
245
264
|
|
|
@@ -10,6 +10,7 @@ from rich.text import Text
|
|
|
10
10
|
|
|
11
11
|
from dreadnode.app.tui.commands import SLASH_COMMANDS
|
|
12
12
|
from dreadnode.app.tui.theme import ACCENT, BORDER_LIGHT, FG_MUTED, FG_SUBTLE
|
|
13
|
+
from dreadnode.app.tui.widgets.context_bar import PRICING_DOCS_URL
|
|
13
14
|
|
|
14
15
|
_CMD_LOOKUP = {cmd.name: cmd for cmd in SLASH_COMMANDS}
|
|
15
16
|
|
|
@@ -52,6 +53,16 @@ _SCREENS: list[tuple[str, str]] = [
|
|
|
52
53
|
("F5", "console"),
|
|
53
54
|
]
|
|
54
55
|
|
|
56
|
+
# Inline explanation of the page-status figures. Phrased so a user reading
|
|
57
|
+
# `?` after seeing `ctx 53.4k/200k tok · ⚒ 12 · usage $0.34` can identify
|
|
58
|
+
# each segment and understand that `usage` cost is in-session-only USD,
|
|
59
|
+
# not balance and not account-wide spend — the unit-mismatch resolution.
|
|
60
|
+
_STATUS_BAR: list[tuple[str, str]] = [
|
|
61
|
+
("ctx N/M tok", "prompt size relative to the model's context limit"),
|
|
62
|
+
("⚒ N", "tool calls this session"),
|
|
63
|
+
("usage $X.XX", "total inference spend this session"),
|
|
64
|
+
]
|
|
65
|
+
|
|
55
66
|
_COMMAND_GROUPS: list[tuple[str, list[str]]] = [
|
|
56
67
|
(
|
|
57
68
|
"Session",
|
|
@@ -105,6 +116,11 @@ def render_help() -> Text:
|
|
|
105
116
|
_section(t, "Agent", _AGENT)
|
|
106
117
|
t.append("\n")
|
|
107
118
|
_section(t, "Screens", _SCREENS)
|
|
119
|
+
t.append("\n")
|
|
120
|
+
_section(t, "Status", _STATUS_BAR)
|
|
121
|
+
t.append(" Credits and pricing ", style=_DESC)
|
|
122
|
+
t.append(PRICING_DOCS_URL, style=f"{_CMD} link {PRICING_DOCS_URL}")
|
|
123
|
+
t.append("\n")
|
|
108
124
|
|
|
109
125
|
t.append("\n")
|
|
110
126
|
t.append(" Commands\n", style=f"bold {_HEADING}")
|
|
@@ -13,7 +13,7 @@ Dreadnode is a terminal-native platform for offensive security agents. You insta
|
|
|
13
13
|
|
|
14
14
|
After the [Quickstart](./quickstart.md), you have:
|
|
15
15
|
|
|
16
|
-
* a logged-in TUI with
|
|
16
|
+
* a logged-in TUI with [pre-loaded credits](../platform/credits.md) attached to your default workspace and project
|
|
17
17
|
* the `web-security` capability installed and runnable against any target you’re authorized to test
|
|
18
18
|
* a session you can replay end-to-end via `/sessions`
|
|
19
19
|
* a markdown vulnerability report in `reports/` for any confirmed findings the agent produced
|
|
@@ -24,6 +24,7 @@ That’s the first-value path. Everything below extends it.
|
|
|
24
24
|
|
|
25
25
|
* **[Quickstart](./quickstart.md)** — install, log in, install `web-security`, run your first pentest.
|
|
26
26
|
* **[Authentication](./authentication.md)** — profiles, workspaces, BYOK provider keys, machine credentials for CI.
|
|
27
|
+
* **[Pricing & credits](../platform/credits.md)** — what credits are, what consumes them, and how to reload before you run your first heavy session.
|
|
27
28
|
* **[AI Red Teaming](https://docs.dreadnode.io/ai-red-teaming/getting-started/tui/)** — different audience, different flow. If you’re testing model targets, start there.
|
|
28
29
|
* **[Self-hosting](https://docs.dreadnode.io/self-hosting/)** — deploy the platform on your own Kubernetes cluster.
|
|
29
30
|
|
|
@@ -127,4 +127,8 @@ The natural fast-follow is **building your own capability** — same shape as `w
|
|
|
127
127
|
|
|
128
128
|
[Build your own capability](https://docs.dreadnode.io/capabilities/quickstart/)
|
|
129
129
|
|
|
130
|
+
Before you go heavy, track what a session costs. Your organization is billed in **credits**, a shared balance that covers inference and sandbox runtime. The `usage $X.XX` figure in the TUI status bar shows your current session’s inference cost in USD. View the Credits page for rates, what consumes credits, and how to reload.
|
|
131
|
+
|
|
132
|
+
[Learn more about credits and pricing](../platform/credits.md)
|
|
133
|
+
|
|
130
134
|
Looking for something else? Browse the [full capability catalog](../capabilities/installing.md) for network ops, recon, and AI red teaming bundles, or read the [AI Red Teaming guide](https://docs.dreadnode.io/ai-red-teaming/) for model-target work.
|