Skip to content

Commit 31179f6

Browse files
committed
feat: simplify workspace structure to use ~/.dreadnode/airt/
- Use clean ~/.dreadnode/airt/[org]/[workspace]/workflows/ structure - Remove complex env var workspace organization - Leverage existing Dreadnode session storage pattern - Get org/workspace from active profile with fallbacks - Update all workflow path definitions consistently - Bump capability version to 1.3.3 Resolves workflow path inconsistencies and aligns with existing ~/.dreadnode/ structure.
1 parent d491b26 commit 31179f6

5 files changed

Lines changed: 67 additions & 29 deletions

File tree

‎capabilities/ai-red-teaming/capability.yaml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
schema: 1
22
name: ai-red-teaming
3-
version: "1.3.2"
3+
version: "1.3.3"
44
description: >
55
Probe the security and safety of AI applications, agents, and foundation models.
66
Orchestrates adversarial attack workflows to discover vulnerabilities in LLMs,

‎capabilities/ai-red-teaming/scripts/attack_runner.py‎

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,28 @@
2222

2323
from dreadnode.app.env import resolve_python_executable
2424

25-
WORKFLOWS_DIR = Path(
26-
os.environ.get(
27-
"AIRT_WORKFLOWS_DIR",
28-
os.path.expanduser("~/workspace/airt/workflows"),
29-
)
30-
)
25+
# Get org/workspace from active profile, with fallbacks
26+
def _get_workspace_path() -> Path:
27+
try:
28+
from dreadnode.app.config import UserConfig
29+
config = UserConfig.read()
30+
profile_data = config.active_profile
31+
if profile_data:
32+
_, profile = profile_data
33+
org_key = profile.organization or "default"
34+
workspace_key = profile.workspace or "main"
35+
else:
36+
org_key = "default"
37+
workspace_key = "main"
38+
except Exception:
39+
# Fallback if config system unavailable
40+
org_key = "default"
41+
workspace_key = "main"
42+
43+
return Path.home() / ".dreadnode" / "airt" / org_key / workspace_key / "workflows"
44+
45+
WORKFLOWS_DIR = Path(os.environ.get("AIRT_WORKFLOWS_DIR")) if os.environ.get("AIRT_WORKFLOWS_DIR") else _get_workspace_path()
46+
METADATA_FILE = WORKFLOWS_DIR / ".workflow_metadata.json"
3147
METADATA_FILE = WORKFLOWS_DIR / ".workflow_metadata.json"
3248

3349
def _resolve_platform_env() -> dict[str, str]:

‎capabilities/ai-red-teaming/scripts/workflow_helper.py‎

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,27 @@
1515

1616
from dreadnode.app.env import resolve_python_executable
1717

18-
WORKFLOWS_DIR = Path(
19-
os.environ.get(
20-
"AIRT_WORKFLOWS_DIR",
21-
os.path.expanduser("~/workspace/airt/workflows"),
22-
)
23-
)
18+
# Get org/workspace from active profile, with fallbacks
19+
def _get_workspace_path() -> Path:
20+
try:
21+
from dreadnode.app.config import UserConfig
22+
config = UserConfig.read()
23+
profile_data = config.active_profile
24+
if profile_data:
25+
_, profile = profile_data
26+
org_key = profile.organization or "default"
27+
workspace_key = profile.workspace or "main"
28+
else:
29+
org_key = "default"
30+
workspace_key = "main"
31+
except Exception:
32+
# Fallback if config system unavailable
33+
org_key = "default"
34+
workspace_key = "main"
35+
36+
return Path.home() / ".dreadnode" / "airt" / org_key / workspace_key / "workflows"
37+
38+
WORKFLOWS_DIR = Path(os.environ.get("AIRT_WORKFLOWS_DIR")) if os.environ.get("AIRT_WORKFLOWS_DIR") else _get_workspace_path()
2439
METADATA_FILE = WORKFLOWS_DIR / ".workflow_metadata.json"
2540

2641

‎capabilities/ai-red-teaming/tools/results.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@
1313

1414
from dreadnode.agents.tools import tool
1515

16+
# Legacy: Local analytics files (use platform data instead)
1617
WORKSPACE_DIR = Path(
17-
os.environ.get("AIRT_OUTPUT_DIR", str(Path.home() / "workspace" / "airt"))
18+
os.environ.get("AIRT_OUTPUT_DIR", str(Path.home() / ".dreadnode" / "airt" / "legacy"))
1819
)
1920

2021

‎capabilities/ai-red-teaming/tools/workflows.py‎

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,27 @@
1717
from dreadnode.agents.tools import tool
1818
from dreadnode.app.env import resolve_python_executable
1919

20-
# Support flexible workspace organization
21-
_base_workspace = Path(os.environ.get("DREADNODE_WORKSPACE_ROOT", str(Path.home() / "workspace")))
22-
_org_key = os.environ.get("DREADNODE_ORG_KEY", "default")
23-
_project_key = os.environ.get("DREADNODE_PROJECT_KEY", "airt")
24-
25-
# Organized structure: ~/workspace/[org]/[project]/workflows
26-
# Falls back to original structure if new env vars not set
27-
WORKFLOWS_DIR = Path(
28-
os.environ.get(
29-
"AIRT_WORKFLOWS_DIR",
30-
str(_base_workspace / _org_key / _project_key / "workflows")
31-
if any([os.environ.get(var) for var in ["DREADNODE_WORKSPACE_ROOT", "DREADNODE_ORG_KEY", "DREADNODE_PROJECT_KEY"]])
32-
else str(Path.home() / "workspace" / "airt" / "workflows"),
33-
)
34-
)
20+
# Get org/workspace from active profile, with fallbacks
21+
def _get_workspace_path() -> Path:
22+
try:
23+
from dreadnode.app.config import UserConfig
24+
config = UserConfig.read()
25+
profile_data = config.active_profile
26+
if profile_data:
27+
_, profile = profile_data
28+
org_key = profile.organization or "default"
29+
workspace_key = profile.workspace or "main"
30+
else:
31+
org_key = "default"
32+
workspace_key = "main"
33+
except Exception:
34+
# Fallback if config system unavailable
35+
org_key = "default"
36+
workspace_key = "main"
37+
38+
return Path.home() / ".dreadnode" / "airt" / org_key / workspace_key / "workflows"
39+
40+
WORKFLOWS_DIR = Path(os.environ.get("AIRT_WORKFLOWS_DIR")) if os.environ.get("AIRT_WORKFLOWS_DIR") else _get_workspace_path()
3541
METADATA_FILE = WORKFLOWS_DIR / ".workflow_metadata.json"
3642

3743

0 commit comments

Comments
 (0)