dreadnode 2.0.12__tar.gz → 2.0.13__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.12 → dreadnode-2.0.13}/PKG-INFO +1 -1
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/client/interactive.py +0 -4
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/client/managed_client.py +47 -24
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/client/runtime_client.py +10 -4
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/server/app.py +30 -10
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/app.py +18 -9
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/command_dispatcher.py +2 -2
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/profile_manager.py +51 -9
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/sessions_manager.py +9 -3
- {dreadnode-2.0.12 → dreadnode-2.0.13}/pyproject.toml +1 -1
- {dreadnode-2.0.12 → dreadnode-2.0.13}/.gitignore +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/LICENSE +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/README.md +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/__main__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/agents/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/agents/agent.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/agents/events.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/agents/exceptions.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/agents/format.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/agents/hooks.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/agents/mcp/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/agents/mcp/auth.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/agents/mcp/client.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/agents/mcp/config.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/agents/mcp/server.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/agents/reactions.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/agents/skills.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/agents/stopping.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/agents/subagent.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/agents/tools.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/agents/trajectory.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/analytics/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/analytics/aggregator.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/analytics/classifier.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/analytics/compliance.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/analytics/engine.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/analytics/recommendations.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/analytics/types.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/assessment.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/autodan_turbo.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/beast.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/compliance/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/compliance/atlas.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/compliance/nist.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/compliance/owasp.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/compliance/owasp_agentic.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/compliance/saif.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/constants.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/crescendo.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/assets/audio/adversarial_query.mp3 +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/assets/image/bomb.jpg +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/assets/image/meth.png +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/prompts/adversarial_benchmark_subset.csv +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/prompts/ai_safety.csv +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/rubrics/data_exfiltration.yaml +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/rubrics/goal_hijacking.yaml +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/rubrics/memory_poisoning.yaml +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/rubrics/privilege_escalation.yaml +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/rubrics/rce.yaml +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/rubrics/scope_creep.yaml +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/rubrics/tool_chaining.yaml +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/rubrics/tool_selection_safety.yaml +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/rubrics/unbounded_agency.yaml +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/rubrics/web_chatbot_security.yaml +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/templates/crescendo/variant_1.yaml +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/templates/crescendo/variant_2.yaml +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/templates/crescendo/variant_3.yaml +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/templates/crescendo/variant_4.yaml +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/templates/crescendo/variant_5.yaml +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/deep_inception.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/drattack.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/events.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/goat.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/gptfuzzer.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/image.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/multimodal.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/pair.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/prompt.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/rainbow.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/renellm.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/reporting/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/reporting/json_report.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/reporting/llm_summary.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/reporting/markdown.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/tap.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/api/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/api/client.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/api/models.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/cli/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/cli/airt.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/cli/args.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/cli/capability.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/cli/dataset.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/cli/evaluation.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/cli/main.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/cli/model.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/cli/optimize.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/cli/runtime.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/cli/sandbox.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/cli/shared.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/cli/task.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/cli/templates/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/cli/templates/init/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/cli/templates/init/challenge/Dockerfile +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/cli/templates/init/docker-compose.yaml +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/cli/templates/init/provision.sh +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/cli/templates/init/solution.sh +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/cli/templates/init/task-remote.yaml.tmpl +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/cli/templates/init/task.yaml.tmpl +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/cli/templates/init/teardown.sh +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/cli/templates/init/verify.sh +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/cli/train.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/cli/worlds.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/client/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/client/models.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/client/transports.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/config.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/env.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/main.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/model_catalog.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/print_mode.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/server/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/server/auth.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/server/capability_manager.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/server/model_resolution.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/server/prompt.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/server/prompt_registry.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/server/runtime_events.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/server/session_hydrator.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/server/session_persistence.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/server/session_policy.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/server/turn_coordinator.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/server/utils.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/server/websocket.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/server/worker_manager.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/auth_flow.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/capabilities_manager.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/commands.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/connection.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/dreadnode.tcss +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/error_handler.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/model_manager.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/model_variants.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/runtime_cache.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/screen_router.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/screens/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/screens/auth.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/screens/base.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/screens/capabilities.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/screens/capability_docs.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/screens/connection_error.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/screens/console.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/screens/environments.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/screens/evaluations.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/screens/model_picker.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/screens/models.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/screens/raw_spans.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/screens/runtimes.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/screens/sandboxes.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/screens/secrets.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/screens/services.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/screens/sessions.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/screens/theme_showcase.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/screens/traces.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/screens/workspaces.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/spans_reader.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/theme.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/tool_format.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/turn_coordinator.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/turn_lifecycle.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/turn_reducer.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/turn_state_phase.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/update_check.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/widgets/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/widgets/agent_dialog.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/widgets/agent_suggester.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/widgets/composer.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/widgets/context_bar.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/widgets/conversation.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/widgets/flash.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/widgets/header_bar.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/widgets/help_panel.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/widgets/mention_overlay.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/widgets/message_queue.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/widgets/overlay_mixin.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/widgets/permission_prompt.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/widgets/profile_dialog.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/widgets/prompt_info.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/widgets/session_sidebar.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/widgets/skills_dialog.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/widgets/slash_overlay.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/widgets/status_bar.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/widgets/throbber.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/widgets/tool.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/widgets/tool_progress.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/widgets/tools_dialog.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/widgets/welcome.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/widgets/whoami.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/app/tui/wire_events.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/builtin_capabilities/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/builtin_capabilities/dreadnode/agents/dreadnode.md +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/builtin_capabilities/dreadnode/capability.yaml +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/SKILL.md +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/capability-components.md +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/capability-improvement.md +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/builtin_capabilities/dreadnode/skills/creating-capabilities/runtime-default-capability.md +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/SKILL.md +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/command-groups.md +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-cli/references/tui-crosswalk.md +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/builtin_capabilities/dreadnode/skills/dreadnode-runtime-reference/SKILL.md +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/builtin_capabilities/dreadnode/system-prompt.md +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/capabilities/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/capabilities/capability.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/capabilities/flags.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/capabilities/loader.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/capabilities/sync.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/capabilities/tool_rules.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/capabilities/types.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/capabilities/worker.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/capabilities/worker_runner.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/conditions.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/discovery.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/environment.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/exceptions.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/execution.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/hook.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/judge.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/load.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/log.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/meta/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/meta/config.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/meta/context.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/meta/hydrate.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/meta/introspect.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/metric.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/object.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/scorer.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/serialization.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/stopping.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/task.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/transforms.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/types/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/types/audio.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/types/base.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/types/common.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/types/image.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/types/object_3d.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/types/table.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/types/text.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/types/video.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/core/util.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/datasets/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/datasets/dataset.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/datasets/hf.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/datasets/local.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/evaluations/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/evaluations/console.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/evaluations/evaluation.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/evaluations/events.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/evaluations/format.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/evaluations/result.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/evaluations/sample.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/generators/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/generators/caching.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/generators/chat.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/generators/data.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/generators/exceptions.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/generators/generator/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/generators/generator/base.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/generators/generator/http.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/generators/generator/litellm_.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/generators/generator/transformers_.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/generators/generator/vllm_.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/generators/message.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/generators/models.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/generators/parsing.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/generators/tokenizer/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/generators/tokenizer/base.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/generators/tokenizer/transformers_.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/generators/utils.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/models/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/models/hf.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/models/local.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/models/model.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/optimization/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/optimization/adapters/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/optimization/adapters/agent.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/optimization/adapters/stack.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/optimization/api.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/optimization/backends/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/optimization/backends/base.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/optimization/backends/gepa.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/optimization/collectors.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/optimization/config.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/optimization/console.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/optimization/events.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/optimization/format.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/optimization/jobs.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/optimization/result.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/optimization/sampler.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/optimization/sampling.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/optimization/search.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/optimization/stopping.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/optimization/study.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/optimization/trial.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/packaging/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/packaging/loader.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/packaging/manifest.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/packaging/oci.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/packaging/package.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/packaging/task_validation.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/py.typed +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/samplers/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/samplers/boundary.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/samplers/fuzzing.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/samplers/graph.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/samplers/grid.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/samplers/image.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/samplers/mapelites.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/samplers/optuna.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/samplers/random.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/samplers/registry.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/samplers/strategy.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/advanced_jailbreak_detection.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/agent_security.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/agentic.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/agentic_workflow.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/classification.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/consistency.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/contains.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/cosine_sim.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/credentials.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/crucible.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/documentation_security.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/exfiltration_detection.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/format.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/harm.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/ide_security.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/image.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/json.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/judge.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/length.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/lexical.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/mcp_security.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/memorization.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/multi_agent_security.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/pii.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/prompt_leak.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/readability.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/reasoning_security.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/sentiment.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/scorers/similarity.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/storage/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/storage/providers.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/storage/session_store.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/storage/storage.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tools/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tools/_ripgrep.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tools/apply_patch.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tools/dreadnode_cli.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tools/editing.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tools/execute.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tools/fetch.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tools/glob.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tools/grep.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tools/interaction.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tools/ls.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tools/memory.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tools/read.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tools/report.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tools/task.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tools/think.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tools/todo.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tools/trajectory_search.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tools/web_search.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tools/write.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tracing/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tracing/constants.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tracing/convert.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tracing/exporter.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tracing/exporters.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tracing/span.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tracing/spans.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/tracing/trace_converter.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/base.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/dpo.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/etl/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/etl/_common.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/etl/rl.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/etl/sft.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/etl/worlds.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/events.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/grpo.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/jobs.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/ppo.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/prime.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/ray/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/ray/async_trainer.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/ray/config.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/ray/coordinator.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/ray/distributed.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/ray/dpo.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/ray/experience.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/ray/fsdp2_learner.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/ray/inference.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/ray/learner.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/ray/multi_turn.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/ray/ppo.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/ray/reward_model.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/ray/rollout_env.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/ray/rollout_worker.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/ray/sft.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/ray/trainer.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/recipes.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/rewards/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/rewards/aggregator.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/rewards/functions.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/rewards/scorer_bridge.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/rewards/shaping.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/rewards/types.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/rollouts/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/rollouts/adapters.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/rollouts/orchestrator.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/rollouts/types.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/rollouts/worlds.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/serving/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/serving/vllm_client.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/sft.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/tinker/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/tinker/config.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/tinker/data.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/tinker/renderer.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/tinker/rl.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/tinker/trainer.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/tinker_sft.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/training/utils.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/__init__.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/advanced_jailbreak.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/adversarial_suffix.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/agent_skill.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/agentic_workflow.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/audio.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/browser_agent_attacks.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/cipher.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/constitutional.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/document.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/documentation_poison.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/encoding.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/exfiltration.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/flip_attack.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/guardrail_bypass.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/ide_injection.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/image.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/injection.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/json_tools.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/language.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/logic_bomb.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/mcp_attacks.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/multi_agent_attacks.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/persuasion.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/perturbation.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/pii_extraction.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/pythonic_tools.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/rag_poisoning.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/reasoning_attacks.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/refine.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/response_steering.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/stylistic.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/substitution.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/swap.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/system_prompt_extraction.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/text.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/video.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/transforms/xml_tools.py +0 -0
- {dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/version.py +0 -0
|
@@ -363,10 +363,6 @@ class _RuntimeInteractiveTransport:
|
|
|
363
363
|
http_transport = self._client._http_client._transport
|
|
364
364
|
if isinstance(http_transport, StreamingASGITransport):
|
|
365
365
|
return await http_transport.websocket_connect(url=interactive_url, headers=headers)
|
|
366
|
-
if self._client._http_client._transport is not None:
|
|
367
|
-
raise RuntimeError(
|
|
368
|
-
"Interactive websocket transport is unavailable with injected HTTP transport"
|
|
369
|
-
)
|
|
370
366
|
|
|
371
367
|
from websockets.asyncio.client import connect
|
|
372
368
|
|
|
@@ -74,6 +74,13 @@ class ManagedRuntimeClient(RuntimeClient):
|
|
|
74
74
|
self._capability_flag_overrides = capability_flag_overrides
|
|
75
75
|
self._system_prompt_append = system_prompt_append
|
|
76
76
|
self._lifecycle_ctx: t.Any = None
|
|
77
|
+
# Serialize concurrent start() callers so the slow in-process boot
|
|
78
|
+
# (capability scan + MCP start + litellm warmup) runs once. The
|
|
79
|
+
# event lets passive consumers (e.g. the TUI notify subscriber)
|
|
80
|
+
# wait for the runtime to come up instead of racing start() and
|
|
81
|
+
# kicking off a second boot with empty credentials.
|
|
82
|
+
self._start_lock = asyncio.Lock()
|
|
83
|
+
self._started_event = asyncio.Event()
|
|
77
84
|
|
|
78
85
|
# ── Platform profile ──────────────────────────────────────────
|
|
79
86
|
|
|
@@ -125,30 +132,46 @@ class ManagedRuntimeClient(RuntimeClient):
|
|
|
125
132
|
if self._started:
|
|
126
133
|
return
|
|
127
134
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
self._started = True
|
|
132
|
-
return
|
|
135
|
+
async with self._start_lock:
|
|
136
|
+
if self._started:
|
|
137
|
+
return
|
|
133
138
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
139
|
+
if self._in_process:
|
|
140
|
+
logger.info("Server start | mode=in-process | url={}", self.server_url)
|
|
141
|
+
await self._start_in_process()
|
|
142
|
+
self._mark_started()
|
|
143
|
+
return
|
|
144
|
+
|
|
145
|
+
if await self._is_healthy():
|
|
146
|
+
logger.info("Server start | mode=external | url={}", self.server_url)
|
|
147
|
+
self._mark_started()
|
|
148
|
+
return
|
|
138
149
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
150
|
+
if not self.auto_start:
|
|
151
|
+
logger.error("Server unreachable | url={} | auto_start=false", self.server_url)
|
|
152
|
+
raise RuntimeError(
|
|
153
|
+
"Could not connect to Dreadnode runtime server at "
|
|
154
|
+
f"{self.server_url}. The --server flag overrides the local runtime "
|
|
155
|
+
"endpoint, not the platform API. Omit --server to auto-start the local "
|
|
156
|
+
"runtime, and use /login --server <url> to set the platform API."
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
logger.info("Server start | mode=spawned | url={}", self.server_url)
|
|
160
|
+
self._spawn_local_server()
|
|
161
|
+
await self._wait_until_healthy()
|
|
162
|
+
self._mark_started()
|
|
163
|
+
|
|
164
|
+
async def wait_until_started(self) -> None:
|
|
165
|
+
"""Block until ``start()`` has successfully brought the server up."""
|
|
166
|
+
await self._started_event.wait()
|
|
167
|
+
|
|
168
|
+
def _mark_started(self) -> None:
|
|
151
169
|
self._started = True
|
|
170
|
+
self._started_event.set()
|
|
171
|
+
|
|
172
|
+
def _mark_stopped(self) -> None:
|
|
173
|
+
self._started = False
|
|
174
|
+
self._started_event.clear()
|
|
152
175
|
|
|
153
176
|
async def close(self) -> None:
|
|
154
177
|
"""Close resources and shut down any managed server."""
|
|
@@ -215,15 +238,15 @@ class ManagedRuntimeClient(RuntimeClient):
|
|
|
215
238
|
|
|
216
239
|
reset_app_state()
|
|
217
240
|
|
|
218
|
-
self.
|
|
241
|
+
self._mark_stopped()
|
|
219
242
|
await self._start_in_process()
|
|
220
|
-
self.
|
|
243
|
+
self._mark_started()
|
|
221
244
|
return
|
|
222
245
|
|
|
223
246
|
await self.close()
|
|
224
247
|
self._owned_process = None
|
|
225
248
|
self._owned_log_file = None
|
|
226
|
-
self.
|
|
249
|
+
self._mark_stopped()
|
|
227
250
|
self._http_client = httpx.AsyncClient(
|
|
228
251
|
base_url=self.server_url,
|
|
229
252
|
timeout=None, # noqa: S113 - long-lived local runtime client intentionally disables global timeout
|
|
@@ -285,11 +285,17 @@ class RuntimeClient:
|
|
|
285
285
|
|
|
286
286
|
# ── Session management ────────────────────────────────────────
|
|
287
287
|
|
|
288
|
-
async def list_sessions(self) -> list[models.SessionInfo]:
|
|
289
|
-
"""List active sessions from the connected server.
|
|
290
|
-
|
|
288
|
+
async def list_sessions(self, *, include_platform: bool = False) -> list[models.SessionInfo]:
|
|
289
|
+
"""List active sessions from the connected server.
|
|
290
|
+
|
|
291
|
+
By default only in-process sessions are returned. Pass
|
|
292
|
+
``include_platform=True`` when the caller needs the full history
|
|
293
|
+
(session picker); it adds a platform API round-trip.
|
|
294
|
+
"""
|
|
295
|
+
logger.debug("Listing sessions | include_platform={}", include_platform)
|
|
291
296
|
await self.start()
|
|
292
|
-
|
|
297
|
+
params = {"include_platform": "true"} if include_platform else None
|
|
298
|
+
response = await self._http_client.get("/api/sessions", params=params)
|
|
293
299
|
response.raise_for_status()
|
|
294
300
|
sessions = [models.SessionInfo.from_dict(item) for item in response.json()]
|
|
295
301
|
logger.debug("Listed sessions | count={}", len(sessions))
|
|
@@ -728,21 +728,37 @@ class ServerState:
|
|
|
728
728
|
"""List all sessions."""
|
|
729
729
|
return list(self._sessions.values())
|
|
730
730
|
|
|
731
|
-
def list_session_infos(self) -> list[SessionInfo]:
|
|
732
|
-
"""List active sessions
|
|
731
|
+
def list_session_infos(self, *, include_platform: bool = False) -> list[SessionInfo]:
|
|
732
|
+
"""List active sessions, optionally merged with platform-persisted sessions.
|
|
733
|
+
|
|
734
|
+
The platform fetch is a ~500ms round-trip that callers only need
|
|
735
|
+
when rendering the full history (session picker, ``/sessions``
|
|
736
|
+
slash command). Boot, runtime swap, and other fast paths skip it
|
|
737
|
+
and get only the in-process set (plus legacy local store).
|
|
738
|
+
"""
|
|
733
739
|
sessions = {session.session_id: session.to_info() for session in self._sessions.values()}
|
|
734
740
|
|
|
735
|
-
#
|
|
736
|
-
#
|
|
737
|
-
#
|
|
738
|
-
#
|
|
741
|
+
# Platform-scoped list — scoped to the current user via ``user_id``
|
|
742
|
+
# and to this SDK runtime via ``DREADNODE_RUNTIME_ID`` (None on
|
|
743
|
+
# local, the sandbox id on remote). ``save_session`` tags new rows
|
|
744
|
+
# with the same env so the filter stays consistent. Without the
|
|
745
|
+
# runtime scope a local SDK server surfaces sessions from every
|
|
746
|
+
# runtime the user has connected to, and the TUI swap-back lands
|
|
747
|
+
# on a stray remote session. Stop-gap until the platform endpoint
|
|
748
|
+
# gains a first-class runtime_id filter.
|
|
749
|
+
own_runtime_id = os.environ.get("DREADNODE_RUNTIME_ID", "").strip() or None
|
|
739
750
|
ctx = self._get_api_context()
|
|
740
|
-
if ctx is not None:
|
|
751
|
+
if include_platform and ctx is not None:
|
|
741
752
|
api, org, ws, user_id = ctx
|
|
742
753
|
try:
|
|
743
754
|
data = api.list_sessions(org, ws, page_size=100, user_id=user_id)
|
|
744
755
|
for s in data.get("sessions", []):
|
|
745
756
|
sid = s.get("id", "")
|
|
757
|
+
session_runtime_id = s.get("runtime_id")
|
|
758
|
+
if session_runtime_id is not None:
|
|
759
|
+
session_runtime_id = str(session_runtime_id)
|
|
760
|
+
if session_runtime_id != own_runtime_id:
|
|
761
|
+
continue
|
|
746
762
|
if sid and sid not in sessions:
|
|
747
763
|
sessions[sid] = SessionInfo(
|
|
748
764
|
session_id=sid,
|
|
@@ -2216,9 +2232,13 @@ class SessionRuntime:
|
|
|
2216
2232
|
|
|
2217
2233
|
|
|
2218
2234
|
@app.get("/api/sessions", response_model=list[SessionInfo])
|
|
2219
|
-
async def list_sessions() -> list[SessionInfo]:
|
|
2220
|
-
"""List
|
|
2221
|
-
|
|
2235
|
+
async def list_sessions(include_platform: bool = False) -> list[SessionInfo]:
|
|
2236
|
+
"""List active agent sessions.
|
|
2237
|
+
|
|
2238
|
+
Defaults to the in-process set; pass ``include_platform=true`` to
|
|
2239
|
+
merge platform-persisted sessions for this runtime (slower).
|
|
2240
|
+
"""
|
|
2241
|
+
return get_state().list_session_infos(include_platform=include_platform)
|
|
2222
2242
|
|
|
2223
2243
|
|
|
2224
2244
|
@app.post("/api/sessions", response_model=SessionInfo)
|
|
@@ -555,8 +555,8 @@ class _AppProfileRuntime:
|
|
|
555
555
|
async def refresh_runtime(self) -> None:
|
|
556
556
|
await self._app._capabilities_manager.refresh()
|
|
557
557
|
|
|
558
|
-
async def refresh_server_sessions(self) -> None:
|
|
559
|
-
await self._app._refresh_server_sessions()
|
|
558
|
+
async def refresh_server_sessions(self, *, include_platform: bool = False) -> None:
|
|
559
|
+
await self._app._refresh_server_sessions(include_platform=include_platform)
|
|
560
560
|
|
|
561
561
|
async def refresh_skill_names(self) -> None:
|
|
562
562
|
await self._app._command_dispatcher.refresh_skill_names()
|
|
@@ -809,8 +809,8 @@ class _AppSessionsTransport:
|
|
|
809
809
|
async def fetch_session_messages(self, session_id: str) -> list[dict[str, t.Any]]:
|
|
810
810
|
return await self._app.managed_client.fetch_session_messages(session_id)
|
|
811
811
|
|
|
812
|
-
async def list_sessions(self) -> list[SessionInfo]:
|
|
813
|
-
return await self._app.managed_client.list_sessions()
|
|
812
|
+
async def list_sessions(self, *, include_platform: bool = False) -> list[SessionInfo]:
|
|
813
|
+
return await self._app.managed_client.list_sessions(include_platform=include_platform)
|
|
814
814
|
|
|
815
815
|
|
|
816
816
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -962,8 +962,8 @@ class _AppCommandActions:
|
|
|
962
962
|
) -> None:
|
|
963
963
|
self._app._run_command(coro_fn, *args)
|
|
964
964
|
|
|
965
|
-
async def refresh_server_sessions(self) -> None:
|
|
966
|
-
await self._app._refresh_server_sessions()
|
|
965
|
+
async def refresh_server_sessions(self, *, include_platform: bool = False) -> None:
|
|
966
|
+
await self._app._refresh_server_sessions(include_platform=include_platform)
|
|
967
967
|
|
|
968
968
|
async def apply_runtime_info(
|
|
969
969
|
self,
|
|
@@ -2456,8 +2456,8 @@ class DreadnodeTextualApp(App[None]):
|
|
|
2456
2456
|
finally:
|
|
2457
2457
|
self._update_check_done = True
|
|
2458
2458
|
|
|
2459
|
-
async def _refresh_server_sessions(self) -> None:
|
|
2460
|
-
await self._sessions_manager.refresh_from_server()
|
|
2459
|
+
async def _refresh_server_sessions(self, *, include_platform: bool = False) -> None:
|
|
2460
|
+
await self._sessions_manager.refresh_from_server(include_platform=include_platform)
|
|
2461
2461
|
|
|
2462
2462
|
@work(exclusive=True, group="session-picker-refresh")
|
|
2463
2463
|
async def _refresh_sessions_then_open_picker(self) -> None:
|
|
@@ -2466,7 +2466,7 @@ class DreadnodeTextualApp(App[None]):
|
|
|
2466
2466
|
|
|
2467
2467
|
if self._is_screen_open(SessionPickerScreen):
|
|
2468
2468
|
return
|
|
2469
|
-
await self._sessions_manager.refresh_from_server()
|
|
2469
|
+
await self._sessions_manager.refresh_from_server(include_platform=True)
|
|
2470
2470
|
self._dismiss_pushed_screens()
|
|
2471
2471
|
self.push_screen(
|
|
2472
2472
|
SessionPickerScreen(
|
|
@@ -3680,6 +3680,8 @@ class DreadnodeTextualApp(App[None]):
|
|
|
3680
3680
|
|
|
3681
3681
|
self._update_remote_status()
|
|
3682
3682
|
self._sync_conversation()
|
|
3683
|
+
if self.active_session_id is not None:
|
|
3684
|
+
self._dismiss_welcome()
|
|
3683
3685
|
|
|
3684
3686
|
async def _on_remote_disconnected(self) -> None:
|
|
3685
3687
|
"""Called after RuntimeConnectionManager.disconnect() succeeds.
|
|
@@ -3691,6 +3693,7 @@ class DreadnodeTextualApp(App[None]):
|
|
|
3691
3693
|
await self._capabilities_manager.refresh()
|
|
3692
3694
|
await self._refresh_server_sessions()
|
|
3693
3695
|
self._update_remote_status()
|
|
3696
|
+
self._sync_conversation()
|
|
3694
3697
|
|
|
3695
3698
|
def _update_remote_status(self) -> None:
|
|
3696
3699
|
"""Update status bar to reflect remote/local connection state."""
|
|
@@ -3724,7 +3727,13 @@ class DreadnodeTextualApp(App[None]):
|
|
|
3724
3727
|
internally (CAP-WCLI-021); this outer loop only exists to survive
|
|
3725
3728
|
server-startup races where the first connect attempt fails before
|
|
3726
3729
|
the local runtime is up.
|
|
3730
|
+
|
|
3731
|
+
Wait for the runtime to be started before calling ``subscribe`` —
|
|
3732
|
+
``subscribe`` would otherwise call ``start()`` itself and race
|
|
3733
|
+
``ProfileManager.boot``, booting the in-process server twice
|
|
3734
|
+
(and the first boot with empty platform credentials).
|
|
3727
3735
|
"""
|
|
3736
|
+
await client.wait_until_started()
|
|
3728
3737
|
backoff = 0.5
|
|
3729
3738
|
while True:
|
|
3730
3739
|
try:
|
|
@@ -151,7 +151,7 @@ class CommandActions(t.Protocol):
|
|
|
151
151
|
"""Spawn ``coro_fn(*args)`` as a tracked worker with auth-error recovery."""
|
|
152
152
|
...
|
|
153
153
|
|
|
154
|
-
async def refresh_server_sessions(self) -> None: ...
|
|
154
|
+
async def refresh_server_sessions(self, *, include_platform: bool = False) -> None: ...
|
|
155
155
|
|
|
156
156
|
async def apply_runtime_info(
|
|
157
157
|
self,
|
|
@@ -532,7 +532,7 @@ class CommandDispatcher:
|
|
|
532
532
|
# ------------------------------------------------------------------
|
|
533
533
|
|
|
534
534
|
async def list_sessions_command(self) -> None:
|
|
535
|
-
await self._actions.refresh_server_sessions()
|
|
535
|
+
await self._actions.refresh_server_sessions(include_platform=True)
|
|
536
536
|
self._actions.write_session_listing()
|
|
537
537
|
|
|
538
538
|
async def reload_capabilities_command(self) -> None:
|
|
@@ -38,6 +38,7 @@ inside a sub-controller.
|
|
|
38
38
|
"""
|
|
39
39
|
|
|
40
40
|
import asyncio
|
|
41
|
+
import contextlib
|
|
41
42
|
import time
|
|
42
43
|
import typing as t
|
|
43
44
|
from dataclasses import dataclass
|
|
@@ -58,6 +59,22 @@ if t.TYPE_CHECKING:
|
|
|
58
59
|
from dreadnode.app.tui.update_check import UpdateInfo
|
|
59
60
|
|
|
60
61
|
|
|
62
|
+
def _log_background_boot_failure(task: "asyncio.Task[t.Any]") -> None:
|
|
63
|
+
"""Surface exceptions from a detached runtime-boot task.
|
|
64
|
+
|
|
65
|
+
When early auth failures cause ``boot()`` to return before awaiting
|
|
66
|
+
the runtime-boot task, the task keeps running in the background so
|
|
67
|
+
a subsequent successful auth can reuse it. Without a done-callback,
|
|
68
|
+
any exception raised by the detached task would be lost at GC time
|
|
69
|
+
as ``Task exception was never retrieved``.
|
|
70
|
+
"""
|
|
71
|
+
if task.cancelled():
|
|
72
|
+
return
|
|
73
|
+
exc = task.exception()
|
|
74
|
+
if exc is not None:
|
|
75
|
+
logger.opt(exception=exc).debug("Background runtime boot failed")
|
|
76
|
+
|
|
77
|
+
|
|
61
78
|
# =============================================================================
|
|
62
79
|
# Shared flow state + ports
|
|
63
80
|
# =============================================================================
|
|
@@ -157,7 +174,7 @@ class ProfileRuntimePort(t.Protocol):
|
|
|
157
174
|
|
|
158
175
|
async def refresh_runtime(self) -> None: ...
|
|
159
176
|
|
|
160
|
-
async def refresh_server_sessions(self) -> None: ...
|
|
177
|
+
async def refresh_server_sessions(self, *, include_platform: bool = False) -> None: ...
|
|
161
178
|
|
|
162
179
|
async def refresh_skill_names(self) -> None: ...
|
|
163
180
|
|
|
@@ -629,6 +646,18 @@ class BootAndAuthRecoveryController:
|
|
|
629
646
|
|
|
630
647
|
org = profile.organization
|
|
631
648
|
workspace = profile.workspace
|
|
649
|
+
|
|
650
|
+
# Kick off the local runtime boot now — it only needs the profile's
|
|
651
|
+
# scalar fields (url/api_key/org/workspace/project), which are already
|
|
652
|
+
# in memory. Running it concurrently with the remaining platform API
|
|
653
|
+
# calls (org/workspace validation, identity hydration, user prefs +
|
|
654
|
+
# LiteLLM key provisioning) collapses the critical path substantially.
|
|
655
|
+
self._runtime.set_api_context(api, org, workspace)
|
|
656
|
+
self._runtime.set_platform_profile(profile)
|
|
657
|
+
runtime_start_t0 = time.monotonic()
|
|
658
|
+
runtime_boot_task = asyncio.create_task(self._runtime.start_local_runtime())
|
|
659
|
+
runtime_boot_task.add_done_callback(_log_background_boot_failure)
|
|
660
|
+
|
|
632
661
|
try:
|
|
633
662
|
t0 = time.monotonic()
|
|
634
663
|
await asyncio.to_thread(api.get_organization, org)
|
|
@@ -643,6 +672,8 @@ class BootAndAuthRecoveryController:
|
|
|
643
672
|
self._invoke_show_auth_modal(
|
|
644
673
|
reason="Could not verify your account — please sign in again"
|
|
645
674
|
)
|
|
675
|
+
# Let the runtime boot finish in the background — a subsequent
|
|
676
|
+
# successful auth will restart it with fresh creds anyway.
|
|
646
677
|
return
|
|
647
678
|
|
|
648
679
|
if not any(getattr(ws, "key", None) == workspace for ws in workspaces):
|
|
@@ -664,12 +695,24 @@ class BootAndAuthRecoveryController:
|
|
|
664
695
|
logger.opt(exception=True).debug("Boot: identity hydration failed (non-fatal)")
|
|
665
696
|
|
|
666
697
|
resume_session_id = self._state.resume_session_id()
|
|
698
|
+
# Platform models + LiteLLM provisioning can overlap with the tail of
|
|
699
|
+
# the runtime boot and the subsequent runtime refreshes.
|
|
700
|
+
platform_models_t0 = time.monotonic()
|
|
701
|
+
platform_models_task = asyncio.create_task(
|
|
702
|
+
self._models.refresh_platform_models_and_key(api)
|
|
703
|
+
)
|
|
667
704
|
try:
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
705
|
+
try:
|
|
706
|
+
await runtime_boot_task
|
|
707
|
+
except BaseException:
|
|
708
|
+
platform_models_task.cancel()
|
|
709
|
+
with contextlib.suppress(BaseException):
|
|
710
|
+
await platform_models_task
|
|
711
|
+
raise
|
|
712
|
+
logger.debug(
|
|
713
|
+
"Boot timing | runtime_start={:.0f}ms",
|
|
714
|
+
(time.monotonic() - runtime_start_t0) * 1000,
|
|
715
|
+
)
|
|
673
716
|
t0 = time.monotonic()
|
|
674
717
|
await self._runtime.refresh_runtime()
|
|
675
718
|
logger.debug("Boot timing | refresh_runtime={:.0f}ms", (time.monotonic() - t0) * 1000)
|
|
@@ -677,11 +720,10 @@ class BootAndAuthRecoveryController:
|
|
|
677
720
|
await self._runtime.refresh_server_sessions()
|
|
678
721
|
logger.debug("Boot timing | refresh_sessions={:.0f}ms", (time.monotonic() - t0) * 1000)
|
|
679
722
|
try:
|
|
680
|
-
|
|
681
|
-
await self._models.refresh_platform_models_and_key(api)
|
|
723
|
+
await platform_models_task
|
|
682
724
|
logger.debug(
|
|
683
725
|
"Boot timing | platform_models_and_key={:.0f}ms",
|
|
684
|
-
(time.monotonic() -
|
|
726
|
+
(time.monotonic() - platform_models_t0) * 1000,
|
|
685
727
|
)
|
|
686
728
|
except AuthenticationError:
|
|
687
729
|
self.handle_authentication_error("Session expired — please sign in again")
|
|
@@ -453,7 +453,7 @@ class SessionsTransportPort(t.Protocol):
|
|
|
453
453
|
|
|
454
454
|
async def fetch_session_messages(self, session_id: str) -> list[dict[str, t.Any]]: ...
|
|
455
455
|
|
|
456
|
-
async def list_sessions(self) -> list[SessionInfo]: ...
|
|
456
|
+
async def list_sessions(self, *, include_platform: bool = False) -> list[SessionInfo]: ...
|
|
457
457
|
|
|
458
458
|
|
|
459
459
|
# =============================================================================
|
|
@@ -540,7 +540,7 @@ class SessionsManager:
|
|
|
540
540
|
# Refresh from server (session list hydration)
|
|
541
541
|
# ------------------------------------------------------------------
|
|
542
542
|
|
|
543
|
-
async def refresh_from_server(self) -> None:
|
|
543
|
+
async def refresh_from_server(self, *, include_platform: bool = False) -> None:
|
|
544
544
|
"""Pull the session list from the runtime server and reconcile.
|
|
545
545
|
|
|
546
546
|
Preserves any locally-cached transcript and TUI-only per-session
|
|
@@ -550,8 +550,14 @@ class SessionsManager:
|
|
|
550
550
|
Promotes the resulting first session to active if the previous
|
|
551
551
|
``active_session_id`` no longer exists. Lazy-loads the active
|
|
552
552
|
session's transcript if the cache is empty.
|
|
553
|
+
|
|
554
|
+
``include_platform`` is forwarded to the runtime server; set it
|
|
555
|
+
to True only when the caller needs the full persisted history
|
|
556
|
+
(session picker, ``/sessions`` slash command). Fast paths — boot,
|
|
557
|
+
runtime swap, auth refresh — leave it False to avoid a ~500ms
|
|
558
|
+
platform round-trip.
|
|
553
559
|
"""
|
|
554
|
-
session_infos = await self._transport.list_sessions()
|
|
560
|
+
session_infos = await self._transport.list_sessions(include_platform=include_platform)
|
|
555
561
|
logger.debug("Sessions refresh | count={}", len(session_infos))
|
|
556
562
|
current_model = self._context.current_model()
|
|
557
563
|
refreshed: dict[str, SessionRecord] = {}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/assets/audio/adversarial_query.mp3
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/prompts/adversarial_benchmark_subset.csv
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/rubrics/tool_selection_safety.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/templates/crescendo/variant_1.yaml
RENAMED
|
File without changes
|
{dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/templates/crescendo/variant_2.yaml
RENAMED
|
File without changes
|
{dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/templates/crescendo/variant_3.yaml
RENAMED
|
File without changes
|
{dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/templates/crescendo/variant_4.yaml
RENAMED
|
File without changes
|
{dreadnode-2.0.12 → dreadnode-2.0.13}/dreadnode/airt/data/templates/crescendo/variant_5.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|