diagram-to-iac 0.6.0__py3-none-any.whl → 0.8.0__py3-none-any.whl
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.
- diagram_to_iac/__init__.py +10 -0
- diagram_to_iac/actions/__init__.py +7 -0
- diagram_to_iac/actions/git_entry.py +174 -0
- diagram_to_iac/actions/supervisor_entry.py +116 -0
- diagram_to_iac/actions/terraform_agent_entry.py +207 -0
- diagram_to_iac/agents/__init__.py +26 -0
- diagram_to_iac/agents/demonstrator_langgraph/__init__.py +10 -0
- diagram_to_iac/agents/demonstrator_langgraph/agent.py +826 -0
- diagram_to_iac/agents/git_langgraph/__init__.py +10 -0
- diagram_to_iac/agents/git_langgraph/agent.py +1018 -0
- diagram_to_iac/agents/git_langgraph/pr.py +146 -0
- diagram_to_iac/agents/hello_langgraph/__init__.py +9 -0
- diagram_to_iac/agents/hello_langgraph/agent.py +621 -0
- diagram_to_iac/agents/policy_agent/__init__.py +15 -0
- diagram_to_iac/agents/policy_agent/agent.py +507 -0
- diagram_to_iac/agents/policy_agent/integration_example.py +191 -0
- diagram_to_iac/agents/policy_agent/tools/__init__.py +14 -0
- diagram_to_iac/agents/policy_agent/tools/tfsec_tool.py +259 -0
- diagram_to_iac/agents/shell_langgraph/__init__.py +21 -0
- diagram_to_iac/agents/shell_langgraph/agent.py +122 -0
- diagram_to_iac/agents/shell_langgraph/detector.py +50 -0
- diagram_to_iac/agents/supervisor_langgraph/__init__.py +17 -0
- diagram_to_iac/agents/supervisor_langgraph/agent.py +1947 -0
- diagram_to_iac/agents/supervisor_langgraph/demonstrator.py +22 -0
- diagram_to_iac/agents/supervisor_langgraph/guards.py +23 -0
- diagram_to_iac/agents/supervisor_langgraph/pat_loop.py +49 -0
- diagram_to_iac/agents/supervisor_langgraph/router.py +9 -0
- diagram_to_iac/agents/terraform_langgraph/__init__.py +15 -0
- diagram_to_iac/agents/terraform_langgraph/agent.py +1216 -0
- diagram_to_iac/agents/terraform_langgraph/parser.py +76 -0
- diagram_to_iac/core/__init__.py +7 -0
- diagram_to_iac/core/agent_base.py +19 -0
- diagram_to_iac/core/enhanced_memory.py +302 -0
- diagram_to_iac/core/errors.py +4 -0
- diagram_to_iac/core/issue_tracker.py +49 -0
- diagram_to_iac/core/memory.py +132 -0
- diagram_to_iac/services/__init__.py +10 -0
- diagram_to_iac/services/observability.py +59 -0
- diagram_to_iac/services/step_summary.py +77 -0
- diagram_to_iac/tools/__init__.py +11 -0
- diagram_to_iac/tools/api_utils.py +108 -26
- diagram_to_iac/tools/git/__init__.py +45 -0
- diagram_to_iac/tools/git/git.py +956 -0
- diagram_to_iac/tools/hello/__init__.py +30 -0
- diagram_to_iac/tools/hello/cal_utils.py +31 -0
- diagram_to_iac/tools/hello/text_utils.py +97 -0
- diagram_to_iac/tools/llm_utils/__init__.py +20 -0
- diagram_to_iac/tools/llm_utils/anthropic_driver.py +87 -0
- diagram_to_iac/tools/llm_utils/base_driver.py +90 -0
- diagram_to_iac/tools/llm_utils/gemini_driver.py +89 -0
- diagram_to_iac/tools/llm_utils/openai_driver.py +93 -0
- diagram_to_iac/tools/llm_utils/router.py +303 -0
- diagram_to_iac/tools/sec_utils.py +4 -2
- diagram_to_iac/tools/shell/__init__.py +17 -0
- diagram_to_iac/tools/shell/shell.py +415 -0
- diagram_to_iac/tools/text_utils.py +277 -0
- diagram_to_iac/tools/tf/terraform.py +851 -0
- diagram_to_iac-0.8.0.dist-info/METADATA +99 -0
- diagram_to_iac-0.8.0.dist-info/RECORD +64 -0
- {diagram_to_iac-0.6.0.dist-info → diagram_to_iac-0.8.0.dist-info}/WHEEL +1 -1
- diagram_to_iac-0.8.0.dist-info/entry_points.txt +4 -0
- diagram_to_iac/agents/codegen_agent.py +0 -0
- diagram_to_iac/agents/consensus_agent.py +0 -0
- diagram_to_iac/agents/deployment_agent.py +0 -0
- diagram_to_iac/agents/github_agent.py +0 -0
- diagram_to_iac/agents/interpretation_agent.py +0 -0
- diagram_to_iac/agents/question_agent.py +0 -0
- diagram_to_iac/agents/supervisor.py +0 -0
- diagram_to_iac/agents/vision_agent.py +0 -0
- diagram_to_iac/core/config.py +0 -0
- diagram_to_iac/tools/cv_utils.py +0 -0
- diagram_to_iac/tools/gh_utils.py +0 -0
- diagram_to_iac/tools/tf_utils.py +0 -0
- diagram_to_iac-0.6.0.dist-info/METADATA +0 -16
- diagram_to_iac-0.6.0.dist-info/RECORD +0 -32
- diagram_to_iac-0.6.0.dist-info/entry_points.txt +0 -2
- {diagram_to_iac-0.6.0.dist-info → diagram_to_iac-0.8.0.dist-info}/top_level.txt +0 -0
diagram_to_iac/__init__.py
CHANGED
@@ -0,0 +1,174 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
"""
|
3
|
+
CLI entrypoint for GitAgent - Phase 5 Implementation
|
4
|
+
|
5
|
+
This module provides a command-line interface for manual execution of the GitAgent,
|
6
|
+
following the established patterns in the diagram-to-iac codebase.
|
7
|
+
|
8
|
+
Usage:
|
9
|
+
python -m diagram_to_iac.actions.git_entry --repo-url https://github.com/user/repo
|
10
|
+
# Or via console script (after update_deps.py adds it to pyproject.toml):
|
11
|
+
git-agent --repo-url https://github.com/user/repo
|
12
|
+
|
13
|
+
Features:
|
14
|
+
- Argument parsing for git operations
|
15
|
+
- JSON output for programmatic consumption
|
16
|
+
- Proper error handling and logging
|
17
|
+
- Integration with existing GitAgent implementation
|
18
|
+
"""
|
19
|
+
|
20
|
+
import argparse
|
21
|
+
import json
|
22
|
+
import sys
|
23
|
+
import logging
|
24
|
+
from typing import Optional
|
25
|
+
|
26
|
+
from diagram_to_iac.agents.git_langgraph.agent import GitAgent, GitAgentInput
|
27
|
+
|
28
|
+
|
29
|
+
def setup_logging(verbose: bool = False) -> None:
|
30
|
+
"""Configure logging for the CLI entrypoint."""
|
31
|
+
level = logging.DEBUG if verbose else logging.INFO
|
32
|
+
logging.basicConfig(
|
33
|
+
level=level,
|
34
|
+
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
35
|
+
datefmt='%Y-%m-%d %H:%M:%S'
|
36
|
+
)
|
37
|
+
|
38
|
+
|
39
|
+
def create_argument_parser() -> argparse.ArgumentParser:
|
40
|
+
"""Create and configure the argument parser following established patterns."""
|
41
|
+
parser = argparse.ArgumentParser(
|
42
|
+
prog='git-agent',
|
43
|
+
description='GitAgent CLI - DevOps automation for git operations',
|
44
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
45
|
+
epilog="""
|
46
|
+
Examples:
|
47
|
+
%(prog)s --repo-url https://github.com/user/repo
|
48
|
+
%(prog)s --query "clone https://github.com/user/repo"
|
49
|
+
%(prog)s --query "open issue in repo: bug report" --verbose
|
50
|
+
"""
|
51
|
+
)
|
52
|
+
|
53
|
+
# Primary input options (mutually exclusive)
|
54
|
+
input_group = parser.add_mutually_exclusive_group(required=True)
|
55
|
+
input_group.add_argument(
|
56
|
+
'--repo-url',
|
57
|
+
type=str,
|
58
|
+
help='Git repository URL to clone'
|
59
|
+
)
|
60
|
+
input_group.add_argument(
|
61
|
+
'--query',
|
62
|
+
type=str,
|
63
|
+
help='DevOps query (git clone, GitHub issue, shell command)'
|
64
|
+
)
|
65
|
+
|
66
|
+
# Optional arguments
|
67
|
+
parser.add_argument(
|
68
|
+
'--thread-id',
|
69
|
+
type=str,
|
70
|
+
help='Optional thread ID for conversation history'
|
71
|
+
)
|
72
|
+
parser.add_argument(
|
73
|
+
'--verbose',
|
74
|
+
action='store_true',
|
75
|
+
help='Enable verbose logging'
|
76
|
+
)
|
77
|
+
parser.add_argument(
|
78
|
+
'--config-path',
|
79
|
+
type=str,
|
80
|
+
help='Path to YAML configuration file'
|
81
|
+
)
|
82
|
+
parser.add_argument(
|
83
|
+
'--memory-type',
|
84
|
+
type=str,
|
85
|
+
choices=['persistent', 'memory', 'langgraph'],
|
86
|
+
default='persistent',
|
87
|
+
help='Type of memory to use (default: persistent)'
|
88
|
+
)
|
89
|
+
|
90
|
+
return parser
|
91
|
+
|
92
|
+
|
93
|
+
def format_output(result: object, indent: int = 2) -> str:
|
94
|
+
"""Format output as JSON with proper indentation."""
|
95
|
+
try:
|
96
|
+
if hasattr(result, 'model_dump'):
|
97
|
+
# Pydantic model
|
98
|
+
return json.dumps(result.model_dump(), indent=indent)
|
99
|
+
else:
|
100
|
+
# Regular object
|
101
|
+
return json.dumps(result, indent=indent, default=str)
|
102
|
+
except Exception as e:
|
103
|
+
# Fallback to string representation
|
104
|
+
logging.warning(f"Failed to serialize output as JSON: {e}")
|
105
|
+
return str(result)
|
106
|
+
|
107
|
+
|
108
|
+
def construct_query_from_repo_url(repo_url: str) -> str:
|
109
|
+
"""Construct a git clone query from a repository URL."""
|
110
|
+
return f"clone repository {repo_url}"
|
111
|
+
|
112
|
+
|
113
|
+
def main() -> int:
|
114
|
+
"""Main entrypoint function following established CLI patterns."""
|
115
|
+
try:
|
116
|
+
# Parse arguments
|
117
|
+
parser = create_argument_parser()
|
118
|
+
args = parser.parse_args()
|
119
|
+
|
120
|
+
# Setup logging
|
121
|
+
setup_logging(args.verbose)
|
122
|
+
logger = logging.getLogger(__name__)
|
123
|
+
|
124
|
+
# Construct query from arguments
|
125
|
+
if args.repo_url:
|
126
|
+
query = construct_query_from_repo_url(args.repo_url)
|
127
|
+
logger.info(f"Constructed query from repo URL: {query}")
|
128
|
+
else:
|
129
|
+
query = args.query
|
130
|
+
logger.info(f"Using provided query: {query}")
|
131
|
+
|
132
|
+
# Initialize agent with optional configuration
|
133
|
+
agent_kwargs = {}
|
134
|
+
if args.config_path:
|
135
|
+
agent_kwargs['config_path'] = args.config_path
|
136
|
+
if args.memory_type:
|
137
|
+
agent_kwargs['memory_type'] = args.memory_type
|
138
|
+
|
139
|
+
logger.info(f"Initializing GitAgent with {agent_kwargs}")
|
140
|
+
agent = GitAgent(**agent_kwargs)
|
141
|
+
|
142
|
+
# Prepare input
|
143
|
+
agent_input = GitAgentInput(
|
144
|
+
query=query,
|
145
|
+
thread_id=args.thread_id
|
146
|
+
)
|
147
|
+
|
148
|
+
logger.info(f"Running agent with input: {agent_input.query}")
|
149
|
+
|
150
|
+
# Execute agent
|
151
|
+
result = agent.run(agent_input)
|
152
|
+
|
153
|
+
# Output results
|
154
|
+
print(format_output(result))
|
155
|
+
|
156
|
+
# Return appropriate exit code
|
157
|
+
if result.error_message:
|
158
|
+
logger.error(f"Agent execution failed: {result.error_message}")
|
159
|
+
return 1
|
160
|
+
else:
|
161
|
+
logger.info("Agent execution completed successfully")
|
162
|
+
return 0
|
163
|
+
|
164
|
+
except KeyboardInterrupt:
|
165
|
+
print("\n⚠️ Operation cancelled by user", file=sys.stderr)
|
166
|
+
return 130
|
167
|
+
except Exception as e:
|
168
|
+
print(f"❌ Error: {e}", file=sys.stderr)
|
169
|
+
logging.exception("Unexpected error in main()")
|
170
|
+
return 1
|
171
|
+
|
172
|
+
|
173
|
+
if __name__ == "__main__":
|
174
|
+
sys.exit(main())
|
@@ -0,0 +1,116 @@
|
|
1
|
+
"""CLI entrypoint for SupervisorAgent."""
|
2
|
+
|
3
|
+
import argparse
|
4
|
+
import json
|
5
|
+
import sys
|
6
|
+
import logging
|
7
|
+
from datetime import datetime
|
8
|
+
from pathlib import Path
|
9
|
+
|
10
|
+
from diagram_to_iac.agents.supervisor_langgraph import (
|
11
|
+
SupervisorAgent,
|
12
|
+
SupervisorAgentInput,
|
13
|
+
)
|
14
|
+
from diagram_to_iac.services import get_log_path, generate_step_summary, reset_log_bus
|
15
|
+
|
16
|
+
|
17
|
+
def setup_logging(verbose: bool = False) -> None:
|
18
|
+
level = logging.DEBUG if verbose else logging.INFO
|
19
|
+
logging.basicConfig(
|
20
|
+
level=level,
|
21
|
+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
22
|
+
datefmt="%Y-%m-%d %H:%M:%S",
|
23
|
+
)
|
24
|
+
|
25
|
+
|
26
|
+
def create_argument_parser() -> argparse.ArgumentParser:
|
27
|
+
parser = argparse.ArgumentParser(
|
28
|
+
prog="supervisor-agent",
|
29
|
+
description="SupervisorAgent CLI - R2D (Repo-to-Deployment) automation",
|
30
|
+
)
|
31
|
+
parser.add_argument("--repo-url", help="Repository URL to operate on")
|
32
|
+
parser.add_argument("--branch-name", help="Branch name (deprecated - supervisor skips branch creation)")
|
33
|
+
parser.add_argument("--thread-id", help="Optional thread id")
|
34
|
+
parser.add_argument("--verbose", action="store_true", help="Enable verbose logging")
|
35
|
+
parser.add_argument("--no-interactive", action="store_true", help="Skip interactive prompts")
|
36
|
+
parser.add_argument("--dry-run", action="store_true", help="Print issue text instead of creating it")
|
37
|
+
return parser
|
38
|
+
|
39
|
+
|
40
|
+
def prompt_for_repo_url() -> str:
|
41
|
+
"""Prompt the user for a repository URL."""
|
42
|
+
try:
|
43
|
+
return input("Repository URL: ").strip()
|
44
|
+
except (KeyboardInterrupt, EOFError):
|
45
|
+
print("\n⚠️ Repository URL required")
|
46
|
+
sys.exit(1)
|
47
|
+
|
48
|
+
|
49
|
+
def format_output(result: object) -> str:
|
50
|
+
try:
|
51
|
+
if hasattr(result, "model_dump"):
|
52
|
+
return json.dumps(result.model_dump(), indent=2)
|
53
|
+
return json.dumps(result, indent=2, default=str)
|
54
|
+
except Exception as e:
|
55
|
+
logging.warning(f"Failed to serialize output: {e}")
|
56
|
+
return str(result)
|
57
|
+
|
58
|
+
|
59
|
+
def main() -> int:
|
60
|
+
parser = create_argument_parser()
|
61
|
+
args = parser.parse_args()
|
62
|
+
|
63
|
+
setup_logging(args.verbose)
|
64
|
+
|
65
|
+
# Handle repo url
|
66
|
+
repo_url = args.repo_url
|
67
|
+
if not repo_url and not args.no_interactive:
|
68
|
+
repo_url = prompt_for_repo_url()
|
69
|
+
elif not repo_url:
|
70
|
+
parser.error("--repo-url is required when --no-interactive is used")
|
71
|
+
|
72
|
+
# Branch name is no longer used since supervisor skips branch creation
|
73
|
+
# All errors are handled via GitHub issues instead
|
74
|
+
branch_name = args.branch_name or "main" # Placeholder for compatibility
|
75
|
+
|
76
|
+
agent = SupervisorAgent()
|
77
|
+
|
78
|
+
|
79
|
+
while True:
|
80
|
+
reset_log_bus()
|
81
|
+
result = agent.run(
|
82
|
+
SupervisorAgentInput(
|
83
|
+
repo_url=repo_url,
|
84
|
+
branch_name=branch_name,
|
85
|
+
thread_id=args.thread_id,
|
86
|
+
dry_run=args.dry_run,
|
87
|
+
)
|
88
|
+
|
89
|
+
)
|
90
|
+
|
91
|
+
print(format_output(result))
|
92
|
+
|
93
|
+
try:
|
94
|
+
generate_step_summary(get_log_path(), Path("step-summary.md"))
|
95
|
+
except Exception as e: # noqa: BLE001
|
96
|
+
logging.warning(f"Step summary generation failed: {e}")
|
97
|
+
|
98
|
+
if result.success or args.no_interactive:
|
99
|
+
break
|
100
|
+
|
101
|
+
try:
|
102
|
+
choice = input("Retry workflow? [y/N]: ").strip().lower()
|
103
|
+
except (KeyboardInterrupt, EOFError):
|
104
|
+
choice = ""
|
105
|
+
|
106
|
+
if choice != "y":
|
107
|
+
break
|
108
|
+
|
109
|
+
repo_url = prompt_for_repo_url()
|
110
|
+
# No longer prompt for branch name since supervisor skips branch creation
|
111
|
+
|
112
|
+
return 0 if result.success else 1
|
113
|
+
|
114
|
+
|
115
|
+
if __name__ == "__main__":
|
116
|
+
sys.exit(main())
|
@@ -0,0 +1,207 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
"""
|
3
|
+
CLI entrypoint for TerraformAgent - Phase 4 Implementation
|
4
|
+
|
5
|
+
This module provides a command-line interface for manual execution of the TerraformAgent,
|
6
|
+
following the established patterns in the diagram-to-iac codebase.
|
7
|
+
|
8
|
+
Usage:
|
9
|
+
python -m diagram_to_iac.actions.terraform_agent_entry --query "terraform init"
|
10
|
+
python -m diagram_to_iac.actions.terraform_agent_entry --repo-path /workspace --operation init
|
11
|
+
# Or via console script (after update_deps.py adds it to pyproject.toml):
|
12
|
+
terraform-agent --query "terraform apply configuration"
|
13
|
+
|
14
|
+
Features:
|
15
|
+
- Argument parsing for terraform operations
|
16
|
+
- JSON output for programmatic consumption
|
17
|
+
- Proper error handling and logging
|
18
|
+
- Integration with existing TerraformAgent implementation
|
19
|
+
- Support for init, plan, apply operations
|
20
|
+
- GitHub issue creation for critical errors
|
21
|
+
"""
|
22
|
+
|
23
|
+
import argparse
|
24
|
+
import json
|
25
|
+
import sys
|
26
|
+
import logging
|
27
|
+
from typing import Optional
|
28
|
+
|
29
|
+
from diagram_to_iac.agents.terraform_langgraph.agent import TerraformAgent, TerraformAgentInput
|
30
|
+
|
31
|
+
|
32
|
+
def setup_logging(verbose: bool = False) -> None:
|
33
|
+
"""Configure logging for the CLI entrypoint."""
|
34
|
+
level = logging.DEBUG if verbose else logging.INFO
|
35
|
+
logging.basicConfig(
|
36
|
+
level=level,
|
37
|
+
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
38
|
+
datefmt='%Y-%m-%d %H:%M:%S'
|
39
|
+
)
|
40
|
+
|
41
|
+
|
42
|
+
def create_argument_parser() -> argparse.ArgumentParser:
|
43
|
+
"""Create and configure the argument parser following established patterns."""
|
44
|
+
parser = argparse.ArgumentParser(
|
45
|
+
prog='terraform-agent',
|
46
|
+
description='TerraformAgent CLI - DevOps automation for terraform operations',
|
47
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
48
|
+
epilog="""
|
49
|
+
Examples:
|
50
|
+
%(prog)s --query "terraform init"
|
51
|
+
%(prog)s --query "terraform plan configuration"
|
52
|
+
%(prog)s --query "terraform apply infrastructure"
|
53
|
+
%(prog)s --repo-path /workspace --operation init --verbose
|
54
|
+
%(prog)s --query "open issue for terraform authentication failure"
|
55
|
+
"""
|
56
|
+
)
|
57
|
+
|
58
|
+
# Primary input options (mutually exclusive)
|
59
|
+
input_group = parser.add_mutually_exclusive_group(required=True)
|
60
|
+
input_group.add_argument(
|
61
|
+
'--query',
|
62
|
+
type=str,
|
63
|
+
help='Terraform DevOps query (init, plan, apply, or error reporting)'
|
64
|
+
)
|
65
|
+
input_group.add_argument(
|
66
|
+
'--repo-path',
|
67
|
+
type=str,
|
68
|
+
help='Repository path for terraform operations (requires --operation)'
|
69
|
+
)
|
70
|
+
|
71
|
+
# Operation type (required when using --repo-path)
|
72
|
+
parser.add_argument(
|
73
|
+
'--operation',
|
74
|
+
type=str,
|
75
|
+
choices=['init', 'plan', 'apply'],
|
76
|
+
help='Terraform operation type (required with --repo-path)'
|
77
|
+
)
|
78
|
+
|
79
|
+
# Optional arguments
|
80
|
+
parser.add_argument(
|
81
|
+
'--thread-id',
|
82
|
+
type=str,
|
83
|
+
help='Optional thread ID for conversation history'
|
84
|
+
)
|
85
|
+
parser.add_argument(
|
86
|
+
'--context',
|
87
|
+
type=str,
|
88
|
+
help='Optional context information for error reporting'
|
89
|
+
)
|
90
|
+
parser.add_argument(
|
91
|
+
'--verbose',
|
92
|
+
action='store_true',
|
93
|
+
help='Enable verbose logging'
|
94
|
+
)
|
95
|
+
parser.add_argument(
|
96
|
+
'--config-path',
|
97
|
+
type=str,
|
98
|
+
help='Path to YAML configuration file'
|
99
|
+
)
|
100
|
+
parser.add_argument(
|
101
|
+
'--memory-type',
|
102
|
+
type=str,
|
103
|
+
choices=['persistent', 'memory', 'langgraph'],
|
104
|
+
default='persistent',
|
105
|
+
help='Type of memory to use (default: persistent)'
|
106
|
+
)
|
107
|
+
|
108
|
+
return parser
|
109
|
+
|
110
|
+
|
111
|
+
def format_output(result: object, indent: int = 2) -> str:
|
112
|
+
"""Format output as JSON with proper indentation."""
|
113
|
+
try:
|
114
|
+
if hasattr(result, 'model_dump'):
|
115
|
+
# Pydantic model
|
116
|
+
return json.dumps(result.model_dump(), indent=indent)
|
117
|
+
else:
|
118
|
+
# Regular object
|
119
|
+
return json.dumps(result, indent=indent, default=str)
|
120
|
+
except Exception as e:
|
121
|
+
# Fallback to string representation
|
122
|
+
logging.warning(f"Failed to serialize output as JSON: {e}")
|
123
|
+
return str(result)
|
124
|
+
|
125
|
+
|
126
|
+
def construct_query_from_repo_path(repo_path: str, operation: str) -> str:
|
127
|
+
"""Construct a terraform query from repository path and operation."""
|
128
|
+
operation_templates = {
|
129
|
+
'init': f"terraform init in {repo_path}",
|
130
|
+
'plan': f"terraform plan in {repo_path}",
|
131
|
+
'apply': f"terraform apply in {repo_path}"
|
132
|
+
}
|
133
|
+
return operation_templates.get(operation, f"terraform {operation} in {repo_path}")
|
134
|
+
|
135
|
+
|
136
|
+
def validate_arguments(args: argparse.Namespace) -> None:
|
137
|
+
"""Validate argument combinations following terraform agent requirements."""
|
138
|
+
if args.repo_path and not args.operation:
|
139
|
+
raise ValueError("--operation is required when using --repo-path")
|
140
|
+
|
141
|
+
|
142
|
+
def main() -> int:
|
143
|
+
"""Main entrypoint function following established CLI patterns."""
|
144
|
+
try:
|
145
|
+
# Parse arguments
|
146
|
+
parser = create_argument_parser()
|
147
|
+
args = parser.parse_args()
|
148
|
+
|
149
|
+
# Validate argument combinations
|
150
|
+
validate_arguments(args)
|
151
|
+
|
152
|
+
# Setup logging
|
153
|
+
setup_logging(args.verbose)
|
154
|
+
logger = logging.getLogger(__name__)
|
155
|
+
|
156
|
+
# Construct query from arguments
|
157
|
+
if args.repo_path:
|
158
|
+
query = construct_query_from_repo_path(args.repo_path, args.operation)
|
159
|
+
logger.info(f"Constructed query from repo path: {query}")
|
160
|
+
else:
|
161
|
+
query = args.query
|
162
|
+
logger.info(f"Using provided query: {query}")
|
163
|
+
|
164
|
+
# Initialize agent with optional configuration
|
165
|
+
agent_kwargs = {}
|
166
|
+
if args.config_path:
|
167
|
+
agent_kwargs['config_path'] = args.config_path
|
168
|
+
if args.memory_type:
|
169
|
+
agent_kwargs['memory_type'] = args.memory_type
|
170
|
+
|
171
|
+
logger.info(f"Initializing TerraformAgent with {agent_kwargs}")
|
172
|
+
agent = TerraformAgent(**agent_kwargs)
|
173
|
+
|
174
|
+
# Prepare input
|
175
|
+
agent_input = TerraformAgentInput(
|
176
|
+
query=query,
|
177
|
+
thread_id=args.thread_id,
|
178
|
+
context=args.context
|
179
|
+
)
|
180
|
+
|
181
|
+
logger.info(f"Running agent with input: {agent_input.query}")
|
182
|
+
|
183
|
+
# Execute agent
|
184
|
+
result = agent.run(agent_input)
|
185
|
+
|
186
|
+
# Output results
|
187
|
+
print(format_output(result))
|
188
|
+
|
189
|
+
# Return appropriate exit code
|
190
|
+
if result.error_message:
|
191
|
+
logger.error(f"Agent execution failed: {result.error_message}")
|
192
|
+
return 1
|
193
|
+
else:
|
194
|
+
logger.info("Agent execution completed successfully")
|
195
|
+
return 0
|
196
|
+
|
197
|
+
except KeyboardInterrupt:
|
198
|
+
print("\n⚠️ Operation cancelled by user", file=sys.stderr)
|
199
|
+
return 130
|
200
|
+
except Exception as e:
|
201
|
+
print(f"❌ Error: {e}", file=sys.stderr)
|
202
|
+
logging.exception("Unexpected error in main()")
|
203
|
+
return 1
|
204
|
+
|
205
|
+
|
206
|
+
if __name__ == "__main__":
|
207
|
+
sys.exit(main())
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# This file makes the 'agents' module a package
|
2
|
+
# and can be used to expose specific agents or functionalities.
|
3
|
+
|
4
|
+
# Import agents from their new organized locations
|
5
|
+
from .hello_langgraph.agent import HelloAgent
|
6
|
+
from .git_langgraph.agent import GitAgent
|
7
|
+
from .supervisor_langgraph.agent import (
|
8
|
+
SupervisorAgent,
|
9
|
+
SupervisorAgentInput,
|
10
|
+
SupervisorAgentOutput,
|
11
|
+
)
|
12
|
+
|
13
|
+
# Maintain backward compatibility with old names
|
14
|
+
HelloLangGraphAgent = HelloAgent
|
15
|
+
GitAgent = GitAgent
|
16
|
+
|
17
|
+
# Export all agent classes
|
18
|
+
__all__ = [
|
19
|
+
"HelloAgent",
|
20
|
+
"GitAgent",
|
21
|
+
"HelloLangGraphAgent", # backward compatibility
|
22
|
+
"GitAgent", # backward compatibility
|
23
|
+
"SupervisorAgent",
|
24
|
+
"SupervisorAgentInput",
|
25
|
+
"SupervisorAgentOutput",
|
26
|
+
]
|
@@ -0,0 +1,10 @@
|
|
1
|
+
"""
|
2
|
+
DemonstratorAgent for intelligent interactive dry-run demonstrations.
|
3
|
+
|
4
|
+
This agent handles all dry-run interactions in an organic, agentic way,
|
5
|
+
keeping the SupervisorAgent clean and focused.
|
6
|
+
"""
|
7
|
+
|
8
|
+
from .agent import DemonstratorAgent, DemonstratorAgentInput, DemonstratorAgentOutput
|
9
|
+
|
10
|
+
__all__ = ["DemonstratorAgent", "DemonstratorAgentInput", "DemonstratorAgentOutput"]
|