ai-cr 3.2.2__py3-none-any.whl → 3.3.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.
Files changed (40) hide show
  1. {ai_cr-3.2.2.dist-info → ai_cr-3.3.0.dist-info}/LICENSE +21 -21
  2. {ai_cr-3.2.2.dist-info → ai_cr-3.3.0.dist-info}/METADATA +1 -1
  3. ai_cr-3.3.0.dist-info/RECORD +41 -0
  4. {ai_cr-3.2.2.dist-info → ai_cr-3.3.0.dist-info}/WHEEL +1 -1
  5. gito/__main__.py +4 -4
  6. gito/bootstrap.py +90 -90
  7. gito/cli.py +255 -244
  8. gito/cli_base.py +104 -94
  9. gito/commands/__init__.py +1 -1
  10. gito/commands/deploy.py +138 -138
  11. gito/commands/fix.py +160 -160
  12. gito/commands/gh_post_review_comment.py +111 -111
  13. gito/commands/gh_react_to_comment.py +217 -217
  14. gito/commands/linear_comment.py +53 -53
  15. gito/commands/repl.py +30 -30
  16. gito/commands/version.py +8 -8
  17. gito/config.toml +450 -448
  18. gito/constants.py +15 -14
  19. gito/context.py +19 -19
  20. gito/core.py +520 -508
  21. gito/env.py +8 -7
  22. gito/gh_api.py +116 -116
  23. gito/issue_trackers.py +50 -50
  24. gito/pipeline.py +83 -83
  25. gito/pipeline_steps/jira.py +62 -62
  26. gito/pipeline_steps/linear.py +85 -85
  27. gito/project_config.py +85 -85
  28. gito/report_struct.py +136 -136
  29. gito/tpl/answer.j2 +25 -25
  30. gito/tpl/github_workflows/components/env-vars.j2 +11 -11
  31. gito/tpl/github_workflows/components/installs.j2 +23 -23
  32. gito/tpl/github_workflows/gito-code-review.yml.j2 +32 -32
  33. gito/tpl/github_workflows/gito-react-to-comments.yml.j2 +70 -70
  34. gito/tpl/partial/aux_files.j2 +8 -8
  35. gito/tpl/questions/changes_summary.j2 +55 -55
  36. gito/tpl/questions/release_notes.j2 +26 -26
  37. gito/tpl/questions/test_cases.j2 +37 -37
  38. gito/utils.py +267 -267
  39. ai_cr-3.2.2.dist-info/RECORD +0 -41
  40. {ai_cr-3.2.2.dist-info → ai_cr-3.3.0.dist-info}/entry_points.txt +0 -0
@@ -1,85 +1,85 @@
1
- import logging
2
- import os
3
- import requests
4
-
5
- import git
6
-
7
- from gito.issue_trackers import IssueTrackerIssue, resolve_issue_key
8
-
9
-
10
- def fetch_issue(issue_key: str, api_key: str = None) -> IssueTrackerIssue | None:
11
- """
12
- Fetch a Linear issue using GraphQL API.
13
- """
14
- api_key = api_key or os.getenv("LINEAR_API_KEY")
15
- try:
16
- url = "https://api.linear.app/graphql"
17
- headers = {
18
- "Authorization": f"{api_key}",
19
- "Content-Type": "application/json"
20
- }
21
-
22
- query = """
23
- query Issues($teamKey: String!, $issueNumber: Float) {
24
- issues(filter: {team: {key: {eq: $teamKey}}, number: {eq: $issueNumber}}) {
25
- nodes {
26
- id
27
- identifier
28
- title
29
- description
30
- url
31
- }
32
- }
33
- }
34
- """
35
- team_key, issue_number = issue_key.split("-")
36
- response = requests.post(
37
- url,
38
- json={
39
- "query": query,
40
- "variables": {'teamKey': team_key, 'issueNumber': int(issue_number)}
41
- },
42
- headers=headers
43
- )
44
- response.raise_for_status()
45
- data = response.json()
46
-
47
- if "errors" in data:
48
- logging.error(f"Linear API error: {data['errors']}")
49
- return None
50
-
51
- nodes = data.get("data", {}).get("issues", {}).get("nodes", [])
52
- if not nodes:
53
- logging.error(f"Linear issue {issue_key} not found")
54
- return None
55
-
56
- issue = nodes[0]
57
- return IssueTrackerIssue(
58
- title=issue["title"],
59
- description=issue.get("description") or "",
60
- url=issue["url"]
61
- )
62
-
63
- except requests.HTTPError as e:
64
- logging.error(f"Failed to fetch Linear issue {issue_key}: {e}")
65
- logging.error(f"Response body: {response.text}")
66
- return None
67
-
68
-
69
- def fetch_associated_issue(
70
- repo: git.Repo,
71
- api_key=None,
72
- **kwargs
73
- ):
74
- """
75
- Pipeline step to fetch a Linear issue based on the current branch name.
76
- """
77
- api_key = api_key or os.getenv("LINEAR_API_KEY")
78
- if not api_key:
79
- logging.error("LINEAR_API_KEY environment variable is not set")
80
- return
81
-
82
- issue_key = resolve_issue_key(repo)
83
- return dict(
84
- associated_issue=fetch_issue(issue_key, api_key)
85
- ) if issue_key else None
1
+ import logging
2
+ import os
3
+ import requests
4
+
5
+ import git
6
+
7
+ from gito.issue_trackers import IssueTrackerIssue, resolve_issue_key
8
+
9
+
10
+ def fetch_issue(issue_key: str, api_key: str = None) -> IssueTrackerIssue | None:
11
+ """
12
+ Fetch a Linear issue using GraphQL API.
13
+ """
14
+ api_key = api_key or os.getenv("LINEAR_API_KEY")
15
+ try:
16
+ url = "https://api.linear.app/graphql"
17
+ headers = {
18
+ "Authorization": f"{api_key}",
19
+ "Content-Type": "application/json"
20
+ }
21
+
22
+ query = """
23
+ query Issues($teamKey: String!, $issueNumber: Float) {
24
+ issues(filter: {team: {key: {eq: $teamKey}}, number: {eq: $issueNumber}}) {
25
+ nodes {
26
+ id
27
+ identifier
28
+ title
29
+ description
30
+ url
31
+ }
32
+ }
33
+ }
34
+ """
35
+ team_key, issue_number = issue_key.split("-")
36
+ response = requests.post(
37
+ url,
38
+ json={
39
+ "query": query,
40
+ "variables": {'teamKey': team_key, 'issueNumber': int(issue_number)}
41
+ },
42
+ headers=headers
43
+ )
44
+ response.raise_for_status()
45
+ data = response.json()
46
+
47
+ if "errors" in data:
48
+ logging.error(f"Linear API error: {data['errors']}")
49
+ return None
50
+
51
+ nodes = data.get("data", {}).get("issues", {}).get("nodes", [])
52
+ if not nodes:
53
+ logging.error(f"Linear issue {issue_key} not found")
54
+ return None
55
+
56
+ issue = nodes[0]
57
+ return IssueTrackerIssue(
58
+ title=issue["title"],
59
+ description=issue.get("description") or "",
60
+ url=issue["url"]
61
+ )
62
+
63
+ except requests.HTTPError as e:
64
+ logging.error(f"Failed to fetch Linear issue {issue_key}: {e}")
65
+ logging.error(f"Response body: {response.text}")
66
+ return None
67
+
68
+
69
+ def fetch_associated_issue(
70
+ repo: git.Repo,
71
+ api_key=None,
72
+ **kwargs
73
+ ):
74
+ """
75
+ Pipeline step to fetch a Linear issue based on the current branch name.
76
+ """
77
+ api_key = api_key or os.getenv("LINEAR_API_KEY")
78
+ if not api_key:
79
+ logging.error("LINEAR_API_KEY environment variable is not set")
80
+ return
81
+
82
+ issue_key = resolve_issue_key(repo)
83
+ return dict(
84
+ associated_issue=fetch_issue(issue_key, api_key)
85
+ ) if issue_key else None
gito/project_config.py CHANGED
@@ -1,85 +1,85 @@
1
- import logging
2
- import tomllib
3
- from dataclasses import dataclass, field
4
- from pathlib import Path
5
-
6
- import microcore as mc
7
- from gito.utils import detect_github_env
8
- from microcore import ui
9
- from git import Repo
10
-
11
- from .constants import PROJECT_CONFIG_BUNDLED_DEFAULTS_FILE, PROJECT_CONFIG_FILE_PATH
12
- from .pipeline import PipelineStep
13
-
14
-
15
- @dataclass
16
- class ProjectConfig:
17
- prompt: str = ""
18
- summary_prompt: str = ""
19
- answer_prompt: str = ""
20
- report_template_md: str = ""
21
- """Markdown report template"""
22
- report_template_cli: str = ""
23
- """Report template for CLI output"""
24
- post_process: str = ""
25
- retries: int = 3
26
- """LLM retries for one request"""
27
- max_code_tokens: int = 32000
28
- prompt_vars: dict = field(default_factory=dict)
29
- mention_triggers: list[str] = field(default_factory=list)
30
- answer_github_comments: bool = field(default=True)
31
- """
32
- Defines the keyword or mention tag that triggers bot actions
33
- when referenced in code review comments.
34
- """
35
- aux_files: list[str] = field(default_factory=list)
36
- pipeline_steps: dict[str, dict | PipelineStep] = field(default_factory=dict)
37
- collapse_previous_code_review_comments: bool = field(default=True)
38
- """
39
- If True, previously added code review comments in the pull request
40
- will be collapsed automatically when a new comment is added.
41
- """
42
-
43
- def __post_init__(self):
44
- self.pipeline_steps = {
45
- k: PipelineStep(**v) if isinstance(v, dict) else v
46
- for k, v in self.pipeline_steps.items()
47
- }
48
-
49
- @staticmethod
50
- def _read_bundled_defaults() -> dict:
51
- with open(PROJECT_CONFIG_BUNDLED_DEFAULTS_FILE, "rb") as f:
52
- config = tomllib.load(f)
53
- return config
54
-
55
- @staticmethod
56
- def load_for_repo(repo: Repo):
57
- return ProjectConfig.load(Path(repo.working_tree_dir) / PROJECT_CONFIG_FILE_PATH)
58
-
59
- @staticmethod
60
- def load(config_path: str | Path | None = None) -> "ProjectConfig":
61
- config = ProjectConfig._read_bundled_defaults()
62
- github_env = detect_github_env()
63
- config["prompt_vars"] |= github_env | dict(github_env=github_env)
64
-
65
- config_path = Path(config_path or PROJECT_CONFIG_FILE_PATH)
66
- if config_path.exists():
67
- logging.info(
68
- f"Loading project-specific configuration from {mc.utils.file_link(config_path)}...")
69
- default_prompt_vars = config["prompt_vars"]
70
- default_pipeline_steps = config["pipeline_steps"]
71
- with open(config_path, "rb") as f:
72
- config.update(tomllib.load(f))
73
- # overriding prompt_vars config section will not empty default values
74
- config["prompt_vars"] = default_prompt_vars | config["prompt_vars"]
75
- # merge individual pipeline steps
76
- for k, v in config["pipeline_steps"].items():
77
- config["pipeline_steps"][k] = default_pipeline_steps.get(k, {}) | v
78
- # merge pipeline steps dict
79
- config["pipeline_steps"] = default_pipeline_steps | config["pipeline_steps"]
80
- else:
81
- logging.info(
82
- f"No project config found at {ui.blue(config_path)}, using defaults"
83
- )
84
-
85
- return ProjectConfig(**config)
1
+ import logging
2
+ import tomllib
3
+ from dataclasses import dataclass, field
4
+ from pathlib import Path
5
+
6
+ import microcore as mc
7
+ from gito.utils import detect_github_env
8
+ from microcore import ui
9
+ from git import Repo
10
+
11
+ from .constants import PROJECT_CONFIG_BUNDLED_DEFAULTS_FILE, PROJECT_CONFIG_FILE_PATH
12
+ from .pipeline import PipelineStep
13
+
14
+
15
+ @dataclass
16
+ class ProjectConfig:
17
+ prompt: str = ""
18
+ summary_prompt: str = ""
19
+ answer_prompt: str = ""
20
+ report_template_md: str = ""
21
+ """Markdown report template"""
22
+ report_template_cli: str = ""
23
+ """Report template for CLI output"""
24
+ post_process: str = ""
25
+ retries: int = 3
26
+ """LLM retries for one request"""
27
+ max_code_tokens: int = 32000
28
+ prompt_vars: dict = field(default_factory=dict)
29
+ mention_triggers: list[str] = field(default_factory=list)
30
+ answer_github_comments: bool = field(default=True)
31
+ """
32
+ Defines the keyword or mention tag that triggers bot actions
33
+ when referenced in code review comments.
34
+ """
35
+ aux_files: list[str] = field(default_factory=list)
36
+ pipeline_steps: dict[str, dict | PipelineStep] = field(default_factory=dict)
37
+ collapse_previous_code_review_comments: bool = field(default=True)
38
+ """
39
+ If True, previously added code review comments in the pull request
40
+ will be collapsed automatically when a new comment is added.
41
+ """
42
+
43
+ def __post_init__(self):
44
+ self.pipeline_steps = {
45
+ k: PipelineStep(**v) if isinstance(v, dict) else v
46
+ for k, v in self.pipeline_steps.items()
47
+ }
48
+
49
+ @staticmethod
50
+ def _read_bundled_defaults() -> dict:
51
+ with open(PROJECT_CONFIG_BUNDLED_DEFAULTS_FILE, "rb") as f:
52
+ config = tomllib.load(f)
53
+ return config
54
+
55
+ @staticmethod
56
+ def load_for_repo(repo: Repo):
57
+ return ProjectConfig.load(Path(repo.working_tree_dir) / PROJECT_CONFIG_FILE_PATH)
58
+
59
+ @staticmethod
60
+ def load(config_path: str | Path | None = None) -> "ProjectConfig":
61
+ config = ProjectConfig._read_bundled_defaults()
62
+ github_env = detect_github_env()
63
+ config["prompt_vars"] |= github_env | dict(github_env=github_env)
64
+
65
+ config_path = Path(config_path or PROJECT_CONFIG_FILE_PATH)
66
+ if config_path.exists():
67
+ logging.info(
68
+ f"Loading project-specific configuration from {mc.utils.file_link(config_path)}...")
69
+ default_prompt_vars = config["prompt_vars"]
70
+ default_pipeline_steps = config["pipeline_steps"]
71
+ with open(config_path, "rb") as f:
72
+ config.update(tomllib.load(f))
73
+ # overriding prompt_vars config section will not empty default values
74
+ config["prompt_vars"] = default_prompt_vars | config["prompt_vars"]
75
+ # merge individual pipeline steps
76
+ for k, v in config["pipeline_steps"].items():
77
+ config["pipeline_steps"][k] = default_pipeline_steps.get(k, {}) | v
78
+ # merge pipeline steps dict
79
+ config["pipeline_steps"] = default_pipeline_steps | config["pipeline_steps"]
80
+ else:
81
+ logging.info(
82
+ f"No project config found at {ui.blue(config_path)}, using defaults"
83
+ )
84
+
85
+ return ProjectConfig(**config)
gito/report_struct.py CHANGED
@@ -1,136 +1,136 @@
1
- import json
2
- import logging
3
- from dataclasses import dataclass, field, asdict
4
- from datetime import datetime
5
- from enum import StrEnum
6
- from pathlib import Path
7
-
8
- import microcore as mc
9
- from colorama import Fore, Style, Back
10
- from microcore.utils import file_link
11
- import textwrap
12
-
13
- from .constants import JSON_REPORT_FILE_NAME, HTML_TEXT_ICON, HTML_CR_COMMENT_MARKER
14
- from .project_config import ProjectConfig
15
- from .utils import syntax_hint, block_wrap_lr, max_line_len, remove_html_comments, filter_kwargs
16
-
17
-
18
- @dataclass
19
- class Issue:
20
- @dataclass
21
- class AffectedCode:
22
- start_line: int = field()
23
- end_line: int | None = field(default=None)
24
- file: str = field(default="")
25
- proposal: str = field(default="")
26
- affected_code: str = field(default="")
27
-
28
- @property
29
- def syntax_hint(self) -> str:
30
- return syntax_hint(self.file)
31
-
32
- id: str = field()
33
- title: str = field()
34
- details: str = field(default="")
35
- severity: int | None = field(default=None)
36
- confidence: int | None = field(default=None)
37
- tags: list[str] = field(default_factory=list)
38
- file: str = field(default="")
39
- affected_lines: list[AffectedCode] = field(default_factory=list)
40
-
41
- def __post_init__(self):
42
- self.affected_lines = [
43
- Issue.AffectedCode(**filter_kwargs(Issue.AffectedCode, dict(file=self.file) | i))
44
- for i in self.affected_lines
45
- ]
46
-
47
- def github_code_link(self, github_env: dict) -> str:
48
- url = (
49
- f"https://github.com/{github_env['github_repo']}"
50
- f"/blob/{github_env['github_pr_sha_or_branch']}"
51
- f"/{self.file}"
52
- )
53
- if self.affected_lines:
54
- url += f"#L{self.affected_lines[0].start_line}"
55
- if self.affected_lines[0].end_line:
56
- url += f"-L{self.affected_lines[0].end_line}"
57
- return url
58
-
59
-
60
- @dataclass
61
- class Report:
62
- class Format(StrEnum):
63
- MARKDOWN = "md"
64
- CLI = "cli"
65
-
66
- issues: dict[str, list[Issue | dict]] = field(default_factory=dict)
67
- summary: str = field(default="")
68
- number_of_processed_files: int = field(default=0)
69
- total_issues: int = field(init=False)
70
- created_at: str = field(default_factory=lambda: datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
71
- model: str = field(default_factory=lambda: mc.config().MODEL)
72
- pipeline_out: dict = field(default_factory=dict)
73
-
74
- @property
75
- def plain_issues(self):
76
- return [
77
- issue
78
- for file, issues in self.issues.items()
79
- for issue in issues
80
- ]
81
-
82
- def __post_init__(self):
83
- issue_id: int = 0
84
- for file in self.issues.keys():
85
- self.issues[file] = [
86
- Issue(
87
- **filter_kwargs(Issue, {
88
- "id": (issue_id := issue_id + 1),
89
- "file": file,
90
- } | issue)
91
- )
92
- for issue in self.issues[file]
93
- ]
94
- self.total_issues = issue_id
95
-
96
- def save(self, file_name: str = ""):
97
- file_name = file_name or JSON_REPORT_FILE_NAME
98
- with open(file_name, "w") as f:
99
- json.dump(asdict(self), f, indent=4)
100
- logging.info(f"Report saved to {mc.utils.file_link(file_name)}")
101
-
102
- @staticmethod
103
- def load(file_name: str | Path = ""):
104
- with open(file_name or JSON_REPORT_FILE_NAME, "r") as f:
105
- data = json.load(f)
106
- data.pop("total_issues", None)
107
- return Report(**data)
108
-
109
- def render(
110
- self,
111
- config: ProjectConfig = None,
112
- report_format: Format = Format.MARKDOWN,
113
- ) -> str:
114
- config = config or ProjectConfig.load()
115
- template = getattr(config, f"report_template_{report_format}")
116
- return mc.prompt(
117
- template,
118
- report=self,
119
- ui=mc.ui,
120
- Fore=Fore,
121
- Style=Style,
122
- Back=Back,
123
- file_link=file_link,
124
- textwrap=textwrap,
125
- block_wrap_lr=block_wrap_lr,
126
- max_line_len=max_line_len,
127
- HTML_TEXT_ICON=HTML_TEXT_ICON,
128
- HTML_CR_COMMENT_MARKER=HTML_CR_COMMENT_MARKER,
129
- remove_html_comments=remove_html_comments,
130
- **config.prompt_vars
131
- )
132
-
133
- def to_cli(self, report_format=Format.CLI):
134
- output = self.render(report_format=report_format)
135
- print("")
136
- print(output)
1
+ import json
2
+ import logging
3
+ from dataclasses import dataclass, field, asdict
4
+ from datetime import datetime
5
+ from enum import StrEnum
6
+ from pathlib import Path
7
+
8
+ import microcore as mc
9
+ from colorama import Fore, Style, Back
10
+ from microcore.utils import file_link
11
+ import textwrap
12
+
13
+ from .constants import JSON_REPORT_FILE_NAME, HTML_TEXT_ICON, HTML_CR_COMMENT_MARKER
14
+ from .project_config import ProjectConfig
15
+ from .utils import syntax_hint, block_wrap_lr, max_line_len, remove_html_comments, filter_kwargs
16
+
17
+
18
+ @dataclass
19
+ class Issue:
20
+ @dataclass
21
+ class AffectedCode:
22
+ start_line: int = field()
23
+ end_line: int | None = field(default=None)
24
+ file: str = field(default="")
25
+ proposal: str = field(default="")
26
+ affected_code: str = field(default="")
27
+
28
+ @property
29
+ def syntax_hint(self) -> str:
30
+ return syntax_hint(self.file)
31
+
32
+ id: str = field()
33
+ title: str = field()
34
+ details: str = field(default="")
35
+ severity: int | None = field(default=None)
36
+ confidence: int | None = field(default=None)
37
+ tags: list[str] = field(default_factory=list)
38
+ file: str = field(default="")
39
+ affected_lines: list[AffectedCode] = field(default_factory=list)
40
+
41
+ def __post_init__(self):
42
+ self.affected_lines = [
43
+ Issue.AffectedCode(**filter_kwargs(Issue.AffectedCode, dict(file=self.file) | i))
44
+ for i in self.affected_lines
45
+ ]
46
+
47
+ def github_code_link(self, github_env: dict) -> str:
48
+ url = (
49
+ f"https://github.com/{github_env['github_repo']}"
50
+ f"/blob/{github_env['github_pr_sha_or_branch']}"
51
+ f"/{self.file}"
52
+ )
53
+ if self.affected_lines:
54
+ url += f"#L{self.affected_lines[0].start_line}"
55
+ if self.affected_lines[0].end_line:
56
+ url += f"-L{self.affected_lines[0].end_line}"
57
+ return url
58
+
59
+
60
+ @dataclass
61
+ class Report:
62
+ class Format(StrEnum):
63
+ MARKDOWN = "md"
64
+ CLI = "cli"
65
+
66
+ issues: dict[str, list[Issue | dict]] = field(default_factory=dict)
67
+ summary: str = field(default="")
68
+ number_of_processed_files: int = field(default=0)
69
+ total_issues: int = field(init=False)
70
+ created_at: str = field(default_factory=lambda: datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
71
+ model: str = field(default_factory=lambda: mc.config().MODEL)
72
+ pipeline_out: dict = field(default_factory=dict)
73
+
74
+ @property
75
+ def plain_issues(self):
76
+ return [
77
+ issue
78
+ for file, issues in self.issues.items()
79
+ for issue in issues
80
+ ]
81
+
82
+ def __post_init__(self):
83
+ issue_id: int = 0
84
+ for file in self.issues.keys():
85
+ self.issues[file] = [
86
+ Issue(
87
+ **filter_kwargs(Issue, {
88
+ "id": (issue_id := issue_id + 1),
89
+ "file": file,
90
+ } | issue)
91
+ )
92
+ for issue in self.issues[file]
93
+ ]
94
+ self.total_issues = issue_id
95
+
96
+ def save(self, file_name: str = ""):
97
+ file_name = file_name or JSON_REPORT_FILE_NAME
98
+ with open(file_name, "w") as f:
99
+ json.dump(asdict(self), f, indent=4)
100
+ logging.info(f"Report saved to {mc.utils.file_link(file_name)}")
101
+
102
+ @staticmethod
103
+ def load(file_name: str | Path = ""):
104
+ with open(file_name or JSON_REPORT_FILE_NAME, "r") as f:
105
+ data = json.load(f)
106
+ data.pop("total_issues", None)
107
+ return Report(**data)
108
+
109
+ def render(
110
+ self,
111
+ config: ProjectConfig = None,
112
+ report_format: Format = Format.MARKDOWN,
113
+ ) -> str:
114
+ config = config or ProjectConfig.load()
115
+ template = getattr(config, f"report_template_{report_format}")
116
+ return mc.prompt(
117
+ template,
118
+ report=self,
119
+ ui=mc.ui,
120
+ Fore=Fore,
121
+ Style=Style,
122
+ Back=Back,
123
+ file_link=file_link,
124
+ textwrap=textwrap,
125
+ block_wrap_lr=block_wrap_lr,
126
+ max_line_len=max_line_len,
127
+ HTML_TEXT_ICON=HTML_TEXT_ICON,
128
+ HTML_CR_COMMENT_MARKER=HTML_CR_COMMENT_MARKER,
129
+ remove_html_comments=remove_html_comments,
130
+ **config.prompt_vars
131
+ )
132
+
133
+ def to_cli(self, report_format=Format.CLI):
134
+ output = self.render(report_format=report_format)
135
+ print("")
136
+ print(output)
gito/tpl/answer.j2 CHANGED
@@ -1,26 +1,26 @@
1
- {{ self_id }}
2
- ----TASK----
3
- Answer the following user question:
4
- --USER QUESTION--
5
- {{ question }}
6
- ----
7
- ----RELATED CODEBASE CHANGES----
8
- {% for part in diff %}{{ part }}\n{% endfor %}
9
-
10
- ----FULL FILE CONTENT AFTER APPLYING CHANGES----
11
- {% for file, file_lines in all_file_lines.items() %}
12
- --FILE: {{ file }}--
13
- {{ file_lines }}
14
- {% endfor %}
15
-
16
- {% include "partial/aux_files.j2" %}
17
-
18
- {%- if pipeline_out.associated_issue and pipeline_out.associated_issue.title %}
19
- ----ASSOCIATED ISSUE----
20
- # {{ pipeline_out.associated_issue.title }}
21
- {{ pipeline_out.associated_issue.description }}
22
- URL: {{ pipeline_out.associated_issue.url }}
23
- {%- endif -%}{{ '\n' }}
24
-
25
- ----ANSWERING INSTRUCTIONS----
1
+ {{ self_id }}
2
+ ----TASK----
3
+ Answer the following user question:
4
+ --USER QUESTION--
5
+ {{ question }}
6
+ ----
7
+ ----RELATED CODEBASE CHANGES----
8
+ {% for part in diff %}{{ part }}\n{% endfor %}
9
+
10
+ ----FULL FILE CONTENT AFTER APPLYING CHANGES----
11
+ {% for file, file_lines in all_file_lines.items() %}
12
+ --FILE: {{ file }}--
13
+ {{ file_lines }}
14
+ {% endfor %}
15
+
16
+ {% include "partial/aux_files.j2" %}
17
+
18
+ {%- if pipeline_out.associated_issue and pipeline_out.associated_issue.title %}
19
+ ----ASSOCIATED ISSUE----
20
+ # {{ pipeline_out.associated_issue.title }}
21
+ {{ pipeline_out.associated_issue.description }}
22
+ URL: {{ pipeline_out.associated_issue.url }}
23
+ {%- endif -%}{{ '\n' }}
24
+
25
+ ----ANSWERING INSTRUCTIONS----
26
26
  {{ answering_instructions }}