diagram-to-iac 0.7.0__tar.gz → 0.8.0__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.
- diagram_to_iac-0.8.0/PKG-INFO +99 -0
- diagram_to_iac-0.8.0/README.md +78 -0
- {diagram_to_iac-0.7.0 → diagram_to_iac-0.8.0}/pyproject.toml +6 -2
- diagram_to_iac-0.8.0/src/diagram_to_iac/__init__.py +10 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/actions/__init__.py +7 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/actions/git_entry.py +174 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/actions/supervisor_entry.py +116 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/actions/terraform_agent_entry.py +207 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/agents/__init__.py +26 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/agents/demonstrator_langgraph/__init__.py +10 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/agents/demonstrator_langgraph/agent.py +826 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/agents/git_langgraph/__init__.py +10 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/agents/git_langgraph/agent.py +1018 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/agents/git_langgraph/pr.py +146 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/agents/hello_langgraph/__init__.py +9 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/agents/hello_langgraph/agent.py +621 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/agents/policy_agent/__init__.py +15 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/agents/policy_agent/agent.py +507 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/agents/policy_agent/integration_example.py +191 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/agents/policy_agent/tools/__init__.py +14 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/agents/policy_agent/tools/tfsec_tool.py +259 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/agents/shell_langgraph/__init__.py +21 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/agents/shell_langgraph/agent.py +122 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/agents/shell_langgraph/detector.py +50 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/agents/supervisor_langgraph/__init__.py +17 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/agents/supervisor_langgraph/agent.py +1947 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/agents/supervisor_langgraph/demonstrator.py +22 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/agents/supervisor_langgraph/guards.py +23 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/agents/supervisor_langgraph/pat_loop.py +49 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/agents/supervisor_langgraph/router.py +9 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/agents/terraform_langgraph/__init__.py +15 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/agents/terraform_langgraph/agent.py +1216 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/agents/terraform_langgraph/parser.py +76 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/core/__init__.py +7 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/core/agent_base.py +19 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/core/enhanced_memory.py +302 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/core/errors.py +4 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/core/issue_tracker.py +49 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/core/memory.py +132 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/services/__init__.py +10 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/services/observability.py +59 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/services/step_summary.py +77 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/tools/__init__.py +11 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/tools/api_utils.py +191 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/tools/git/__init__.py +45 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/tools/git/git.py +956 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/tools/hello/__init__.py +30 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/tools/hello/cal_utils.py +31 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/tools/hello/text_utils.py +97 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/tools/llm_utils/__init__.py +20 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/tools/llm_utils/anthropic_driver.py +87 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/tools/llm_utils/base_driver.py +90 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/tools/llm_utils/gemini_driver.py +89 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/tools/llm_utils/openai_driver.py +93 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/tools/llm_utils/router.py +303 -0
- {diagram_to_iac-0.7.0 → diagram_to_iac-0.8.0}/src/diagram_to_iac/tools/sec_utils.py +4 -2
- diagram_to_iac-0.8.0/src/diagram_to_iac/tools/shell/__init__.py +17 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/tools/shell/shell.py +415 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/tools/text_utils.py +277 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac/tools/tf/terraform.py +851 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac.egg-info/PKG-INFO +99 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac.egg-info/SOURCES.txt +67 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac.egg-info/entry_points.txt +4 -0
- diagram_to_iac-0.8.0/src/diagram_to_iac.egg-info/requires.txt +14 -0
- diagram_to_iac-0.7.0/PKG-INFO +0 -16
- diagram_to_iac-0.7.0/README.md +0 -2
- diagram_to_iac-0.7.0/src/diagram_to_iac/__init__.py +0 -0
- diagram_to_iac-0.7.0/src/diagram_to_iac/agents/__init__.py +0 -0
- diagram_to_iac-0.7.0/src/diagram_to_iac/agents/codegen_agent.py +0 -0
- diagram_to_iac-0.7.0/src/diagram_to_iac/agents/consensus_agent.py +0 -0
- diagram_to_iac-0.7.0/src/diagram_to_iac/agents/deployment_agent.py +0 -0
- diagram_to_iac-0.7.0/src/diagram_to_iac/agents/github_agent.py +0 -0
- diagram_to_iac-0.7.0/src/diagram_to_iac/agents/interpretation_agent.py +0 -0
- diagram_to_iac-0.7.0/src/diagram_to_iac/agents/question_agent.py +0 -0
- diagram_to_iac-0.7.0/src/diagram_to_iac/agents/supervisor.py +0 -0
- diagram_to_iac-0.7.0/src/diagram_to_iac/agents/vision_agent.py +0 -0
- diagram_to_iac-0.7.0/src/diagram_to_iac/core/__init__.py +0 -0
- diagram_to_iac-0.7.0/src/diagram_to_iac/core/agent_base.py +0 -0
- diagram_to_iac-0.7.0/src/diagram_to_iac/core/config.py +0 -0
- diagram_to_iac-0.7.0/src/diagram_to_iac/core/memory.py +0 -0
- diagram_to_iac-0.7.0/src/diagram_to_iac/tools/__init__.py +0 -0
- diagram_to_iac-0.7.0/src/diagram_to_iac/tools/api_utils.py +0 -109
- diagram_to_iac-0.7.0/src/diagram_to_iac/tools/cv_utils.py +0 -0
- diagram_to_iac-0.7.0/src/diagram_to_iac/tools/gh_utils.py +0 -0
- diagram_to_iac-0.7.0/src/diagram_to_iac/tools/llm_utils/__init__.py +0 -0
- diagram_to_iac-0.7.0/src/diagram_to_iac/tools/llm_utils/anthropic_driver.py +0 -0
- diagram_to_iac-0.7.0/src/diagram_to_iac/tools/llm_utils/gemini_driver.py +0 -0
- diagram_to_iac-0.7.0/src/diagram_to_iac/tools/llm_utils/openai_driver.py +0 -0
- diagram_to_iac-0.7.0/src/diagram_to_iac/tools/llm_utils/router.py +0 -0
- diagram_to_iac-0.7.0/src/diagram_to_iac/tools/tf_utils.py +0 -0
- diagram_to_iac-0.7.0/src/diagram_to_iac.egg-info/PKG-INFO +0 -16
- diagram_to_iac-0.7.0/src/diagram_to_iac.egg-info/SOURCES.txt +0 -41
- diagram_to_iac-0.7.0/src/diagram_to_iac.egg-info/entry_points.txt +0 -2
- diagram_to_iac-0.7.0/src/diagram_to_iac.egg-info/requires.txt +0 -7
- diagram_to_iac-0.7.0/tests/test_aiapi_connection.py +0 -0
- diagram_to_iac-0.7.0/tests/test_codegen.py +0 -0
- diagram_to_iac-0.7.0/tests/test_consensus.py +0 -0
- diagram_to_iac-0.7.0/tests/test_end_to_end.py +0 -0
- diagram_to_iac-0.7.0/tests/test_interpretation.py +0 -0
- diagram_to_iac-0.7.0/tests/test_vision.py +0 -0
- {diagram_to_iac-0.7.0 → diagram_to_iac-0.8.0}/setup.cfg +0 -0
- {diagram_to_iac-0.7.0 → diagram_to_iac-0.8.0}/src/diagram_to_iac/cli.py +0 -0
- {diagram_to_iac-0.7.0 → diagram_to_iac-0.8.0}/src/diagram_to_iac/r2d.py +0 -0
- {diagram_to_iac-0.7.0 → diagram_to_iac-0.8.0}/src/diagram_to_iac.egg-info/dependency_links.txt +0 -0
- {diagram_to_iac-0.7.0 → diagram_to_iac-0.8.0}/src/diagram_to_iac.egg-info/top_level.txt +0 -0
@@ -0,0 +1,99 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: diagram-to-iac
|
3
|
+
Version: 0.8.0
|
4
|
+
Summary: Convert architecture diagrams into IaC modules
|
5
|
+
Author-email: vindpro <admin@vindpro.com>
|
6
|
+
Description-Content-Type: text/markdown
|
7
|
+
Requires-Dist: anthropic==0.54.0
|
8
|
+
Requires-Dist: google_api_python_client==2.172.0
|
9
|
+
Requires-Dist: langchain_anthropic==0.3.15
|
10
|
+
Requires-Dist: langchain-core<1.0.0,>=0.3.62
|
11
|
+
Requires-Dist: langchain_google_genai==2.1.5
|
12
|
+
Requires-Dist: langchain_openai==0.3.24
|
13
|
+
Requires-Dist: langgraph==0.4.8
|
14
|
+
Requires-Dist: openai==1.88.0
|
15
|
+
Requires-Dist: protobuf>=5.27.0
|
16
|
+
Requires-Dist: pydantic==2.11.7
|
17
|
+
Requires-Dist: PyYAML==6.0.2
|
18
|
+
Requires-Dist: Requests==2.32.4
|
19
|
+
Requires-Dist: GitPython<4.0,>=3.1
|
20
|
+
Requires-Dist: pytest-mock<4.0.0,>=3.10.0
|
21
|
+
|
22
|
+
# diagram-to-iac
|
23
|
+
An automated system that intelligently translates visual cloud infrastructure diagrams (specifically Azure) into deployable Infrastructure as Code (IaC). The project leverages AI for analysis and GitHub for collaborative refinement.
|
24
|
+
|
25
|
+
## Installation
|
26
|
+
|
27
|
+
Create a virtual environment with Python 3.11+ and install the project in editable mode. Development dependencies (linting, testing, etc.) are provided through the `dev` extra:
|
28
|
+
|
29
|
+
```bash
|
30
|
+
pip install -e .[dev]
|
31
|
+
```
|
32
|
+
|
33
|
+
## Running the CLI
|
34
|
+
|
35
|
+
The project exposes several entry points via `pyproject.toml`. The main one for end‑to‑end automation is `supervisor-agent`.
|
36
|
+
|
37
|
+
```bash
|
38
|
+
supervisor-agent --help
|
39
|
+
```
|
40
|
+
|
41
|
+
Running `supervisor-agent` without arguments enters an interactive mode. You will be prompted for the repository URL and branch name:
|
42
|
+
|
43
|
+
```bash
|
44
|
+
$ supervisor-agent --dry-run
|
45
|
+
Repository URL: https://github.com/octocat/Hello-World.git
|
46
|
+
🚀 R2D SupervisorAgent - Branch Creation
|
47
|
+
📅 Default branch name: r2d-<timestamp>
|
48
|
+
📝 Press Enter to use default, or type a custom branch name:
|
49
|
+
Branch name:
|
50
|
+
```
|
51
|
+
|
52
|
+
The agent will then continue with the workflow (cloning, analysis and issue creation). The `--dry-run` flag prints the generated issue text instead of creating it.
|
53
|
+
|
54
|
+
## Running Tests
|
55
|
+
|
56
|
+
All tests use `pytest` and are located under the `tests` directory. After installing the development dependencies, run:
|
57
|
+
|
58
|
+
```bash
|
59
|
+
pytest
|
60
|
+
```
|
61
|
+
|
62
|
+
## Logs and Observability
|
63
|
+
|
64
|
+
Each run creates a JSONL log file under the `logs/` directory (e.g. `logs/run-<timestamp>.jsonl`).
|
65
|
+
Every significant event emitted by the agents is appended as a single JSON line.
|
66
|
+
You can inspect the log with tools like `tail` to follow the workflow progress:
|
67
|
+
|
68
|
+
```bash
|
69
|
+
tail -f logs/run-*.jsonl
|
70
|
+
```
|
71
|
+
|
72
|
+
|
73
|
+
In CI runs, the `logs/` directory and any `*.tfplan` files are compressed and
|
74
|
+
uploaded as the `logs-and-plans` artifact. Download this artifact from the
|
75
|
+
workflow run to inspect full logs and Terraform plans.
|
76
|
+
|
77
|
+
|
78
|
+
After each workflow run, a Markdown dashboard is generated at `step-summary.md`
|
79
|
+
showing a high level overview of Terraform modules, resource changes and tfsec
|
80
|
+
findings. The dashboard is derived from the JSONL logs and can be viewed
|
81
|
+
directly in the repository or uploaded as a build artifact.
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
This repository provides a container action that runs the `SupervisorAgent` on the current repository. Add the action to a workflow as shown below:
|
86
|
+
|
87
|
+
```yaml
|
88
|
+
jobs:
|
89
|
+
supervisor:
|
90
|
+
runs-on: ubuntu-latest
|
91
|
+
steps:
|
92
|
+
- uses: actions/checkout@v4
|
93
|
+
- name: Run Supervisor Agent
|
94
|
+
uses: ./.github/actions/supervisor
|
95
|
+
env:
|
96
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
97
|
+
```
|
98
|
+
|
99
|
+
The action reads `GITHUB_REPOSITORY` and `GITHUB_TOKEN` automatically to clone the repository and execute the agent.
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# diagram-to-iac
|
2
|
+
An automated system that intelligently translates visual cloud infrastructure diagrams (specifically Azure) into deployable Infrastructure as Code (IaC). The project leverages AI for analysis and GitHub for collaborative refinement.
|
3
|
+
|
4
|
+
## Installation
|
5
|
+
|
6
|
+
Create a virtual environment with Python 3.11+ and install the project in editable mode. Development dependencies (linting, testing, etc.) are provided through the `dev` extra:
|
7
|
+
|
8
|
+
```bash
|
9
|
+
pip install -e .[dev]
|
10
|
+
```
|
11
|
+
|
12
|
+
## Running the CLI
|
13
|
+
|
14
|
+
The project exposes several entry points via `pyproject.toml`. The main one for end‑to‑end automation is `supervisor-agent`.
|
15
|
+
|
16
|
+
```bash
|
17
|
+
supervisor-agent --help
|
18
|
+
```
|
19
|
+
|
20
|
+
Running `supervisor-agent` without arguments enters an interactive mode. You will be prompted for the repository URL and branch name:
|
21
|
+
|
22
|
+
```bash
|
23
|
+
$ supervisor-agent --dry-run
|
24
|
+
Repository URL: https://github.com/octocat/Hello-World.git
|
25
|
+
🚀 R2D SupervisorAgent - Branch Creation
|
26
|
+
📅 Default branch name: r2d-<timestamp>
|
27
|
+
📝 Press Enter to use default, or type a custom branch name:
|
28
|
+
Branch name:
|
29
|
+
```
|
30
|
+
|
31
|
+
The agent will then continue with the workflow (cloning, analysis and issue creation). The `--dry-run` flag prints the generated issue text instead of creating it.
|
32
|
+
|
33
|
+
## Running Tests
|
34
|
+
|
35
|
+
All tests use `pytest` and are located under the `tests` directory. After installing the development dependencies, run:
|
36
|
+
|
37
|
+
```bash
|
38
|
+
pytest
|
39
|
+
```
|
40
|
+
|
41
|
+
## Logs and Observability
|
42
|
+
|
43
|
+
Each run creates a JSONL log file under the `logs/` directory (e.g. `logs/run-<timestamp>.jsonl`).
|
44
|
+
Every significant event emitted by the agents is appended as a single JSON line.
|
45
|
+
You can inspect the log with tools like `tail` to follow the workflow progress:
|
46
|
+
|
47
|
+
```bash
|
48
|
+
tail -f logs/run-*.jsonl
|
49
|
+
```
|
50
|
+
|
51
|
+
|
52
|
+
In CI runs, the `logs/` directory and any `*.tfplan` files are compressed and
|
53
|
+
uploaded as the `logs-and-plans` artifact. Download this artifact from the
|
54
|
+
workflow run to inspect full logs and Terraform plans.
|
55
|
+
|
56
|
+
|
57
|
+
After each workflow run, a Markdown dashboard is generated at `step-summary.md`
|
58
|
+
showing a high level overview of Terraform modules, resource changes and tfsec
|
59
|
+
findings. The dashboard is derived from the JSONL logs and can be viewed
|
60
|
+
directly in the repository or uploaded as a build artifact.
|
61
|
+
|
62
|
+
|
63
|
+
|
64
|
+
This repository provides a container action that runs the `SupervisorAgent` on the current repository. Add the action to a workflow as shown below:
|
65
|
+
|
66
|
+
```yaml
|
67
|
+
jobs:
|
68
|
+
supervisor:
|
69
|
+
runs-on: ubuntu-latest
|
70
|
+
steps:
|
71
|
+
- uses: actions/checkout@v4
|
72
|
+
- name: Run Supervisor Agent
|
73
|
+
uses: ./.github/actions/supervisor
|
74
|
+
env:
|
75
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
76
|
+
```
|
77
|
+
|
78
|
+
The action reads `GITHUB_REPOSITORY` and `GITHUB_TOKEN` automatically to clone the repository and execute the agent.
|
@@ -4,14 +4,18 @@ build-backend = "setuptools.build_meta"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "diagram-to-iac"
|
7
|
-
version = "0.
|
7
|
+
version = "0.8.0"
|
8
8
|
description = "Convert architecture diagrams into IaC modules"
|
9
9
|
readme = "README.md"
|
10
10
|
authors = [{ name="vindpro", email="admin@vindpro.com" }]
|
11
|
-
dependencies = ["anthropic==0.
|
11
|
+
dependencies = ["anthropic==0.54.0", "google_api_python_client==2.172.0", "langchain_anthropic==0.3.15", "langchain-core>=0.3.62,<1.0.0", "langchain_google_genai==2.1.5", "langchain_openai==0.3.24", "langgraph==0.4.8", "openai==1.88.0", "protobuf>=5.27.0", "pydantic==2.11.7", "PyYAML==6.0.2", "Requests==2.32.4", "GitPython>=3.1,<4.0", "pytest-mock>=3.10.0,<4.0.0"] # ← always overwritten by update_deps.py
|
12
|
+
|
13
|
+
|
12
14
|
|
13
15
|
[project.scripts]
|
14
16
|
diagram-to-iac = "diagram_to_iac.cli:main"
|
17
|
+
git-agent = "diagram_to_iac.actions.git_entry:main"
|
18
|
+
supervisor-agent = "diagram_to_iac.actions.supervisor_entry:main"
|
15
19
|
|
16
20
|
[tool.setuptools] # (intentionally left empty)
|
17
21
|
|
@@ -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())
|