agentic-devtools 0.2.511__py3-none-any.whl → 0.2.512__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.
- agentic_devtools/_version.py +2 -2
- agentic_devtools/cli/ci/github_provider.py +45 -0
- agentic_devtools/cli/ci/pipeline/actions/request_review.py +1 -1
- agentic_devtools/cli/ci/pipeline/actions/takeover.py +22 -0
- agentic_devtools/cli/ci/pipeline/runner.py +61 -27
- {agentic_devtools-0.2.511.dist-info → agentic_devtools-0.2.512.dist-info}/METADATA +1 -1
- {agentic_devtools-0.2.511.dist-info → agentic_devtools-0.2.512.dist-info}/RECORD +10 -10
- {agentic_devtools-0.2.511.dist-info → agentic_devtools-0.2.512.dist-info}/WHEEL +0 -0
- {agentic_devtools-0.2.511.dist-info → agentic_devtools-0.2.512.dist-info}/entry_points.txt +0 -0
- {agentic_devtools-0.2.511.dist-info → agentic_devtools-0.2.512.dist-info}/licenses/LICENSE +0 -0
agentic_devtools/_version.py
CHANGED
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.2.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 2,
|
|
21
|
+
__version__ = version = '0.2.512'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 2, 512)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -3606,6 +3606,51 @@ class GitHubActionsProvider(CIPlatformProvider):
|
|
|
3606
3606
|
declared_author_comment_counts_by_review=declared_author_comment_counts_by_review,
|
|
3607
3607
|
)
|
|
3608
3608
|
|
|
3609
|
+
# Attempt direct Agent Tasks API dispatch if configured
|
|
3610
|
+
use_agent_tasks = os.environ.get("AGDT_USE_AGENT_TASKS_API", "").lower() in ("true", "1", "yes")
|
|
3611
|
+
if use_agent_tasks and repo and "/" in repo:
|
|
3612
|
+
try:
|
|
3613
|
+
from agentic_devtools.ai_providers.agent_tasks_payload import (
|
|
3614
|
+
AGENT_TASKS_ENDPOINT_TEMPLATE,
|
|
3615
|
+
build_agent_tasks_payload,
|
|
3616
|
+
)
|
|
3617
|
+
|
|
3618
|
+
pr_meta = self.get_pr_metadata(pr_number)
|
|
3619
|
+
owner, repo_name = repo.split("/", 1)
|
|
3620
|
+
endpoint = AGENT_TASKS_ENDPOINT_TEMPLATE.format(owner=owner, repo=repo_name)
|
|
3621
|
+
payload = build_agent_tasks_payload(
|
|
3622
|
+
prompt=body,
|
|
3623
|
+
model=os.environ.get("COPILOT_AGENT_MODEL", "claude-sonnet-5"),
|
|
3624
|
+
base_ref=pr_meta.base_branch,
|
|
3625
|
+
head_ref=pr_meta.head_branch,
|
|
3626
|
+
)
|
|
3627
|
+
api_resp = _gh_api(
|
|
3628
|
+
endpoint,
|
|
3629
|
+
method="POST",
|
|
3630
|
+
body=payload,
|
|
3631
|
+
token=token,
|
|
3632
|
+
)
|
|
3633
|
+
task_data = json.loads(api_resp)
|
|
3634
|
+
task_url = task_data.get("html_url") or task_data.get("url") or ""
|
|
3635
|
+
logger.info("PR #%d: Dispatched repair via Agent Tasks API: %s", pr_number, task_url)
|
|
3636
|
+
trigger_marker = f"<!-- copilot-trigger:{review_id} -->" if review_id > 0 else ""
|
|
3637
|
+
from agentic_devtools.cli.ci.pipeline.summary import _find_active_summary_comment
|
|
3638
|
+
|
|
3639
|
+
summary_comment = _find_active_summary_comment(self, pr_number)
|
|
3640
|
+
if summary_comment is not None:
|
|
3641
|
+
s_id, s_body = summary_comment
|
|
3642
|
+
session_note = (
|
|
3643
|
+
f"\n\n🤖 **Active Copilot Repair Session**: [View Task Logs]({task_url})\n{trigger_marker}"
|
|
3644
|
+
)
|
|
3645
|
+
self.update_comment(s_id, f"{s_body}{session_note}")
|
|
3646
|
+
return 1
|
|
3647
|
+
except Exception as exc:
|
|
3648
|
+
logger.warning(
|
|
3649
|
+
"PR #%d: Agent Tasks API dispatch failed, falling back to comment: %s",
|
|
3650
|
+
pr_number,
|
|
3651
|
+
exc,
|
|
3652
|
+
)
|
|
3653
|
+
|
|
3609
3654
|
response = self._post_repair_comment(pr_number=pr_number, body=body, token=token)
|
|
3610
3655
|
data = json.loads(response)
|
|
3611
3656
|
return data["id"]
|
|
@@ -14,7 +14,7 @@ from agentic_devtools.cli.shared.retry import ProviderRateLimitError
|
|
|
14
14
|
|
|
15
15
|
logger = logging.getLogger(__name__)
|
|
16
16
|
|
|
17
|
-
_EFFECTIVE_REVIEW_STATES = {"APPROVED", "CHANGES_REQUESTED"}
|
|
17
|
+
_EFFECTIVE_REVIEW_STATES = {"APPROVED", "CHANGES_REQUESTED", "COMMENTED"}
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class RequestReviewAction:
|
|
@@ -125,6 +125,28 @@ class TakeOverAutomationCommitAction:
|
|
|
125
125
|
preserves_diff_fingerprint=True,
|
|
126
126
|
)
|
|
127
127
|
except Exception as exc:
|
|
128
|
+
if isinstance(exc, ProviderRateLimitError) and exc.is_rate_limit:
|
|
129
|
+
raise
|
|
130
|
+
if "Head SHA changed before Copilot takeover" in str(exc):
|
|
131
|
+
logger.warning(
|
|
132
|
+
"PR #%d: takeover skipped due to concurrent branch update: %s",
|
|
133
|
+
snapshot.pr_number,
|
|
134
|
+
exc,
|
|
135
|
+
)
|
|
136
|
+
return ActionResult(
|
|
137
|
+
name=self.name,
|
|
138
|
+
decision=ActionDecision.SKIP,
|
|
139
|
+
details=f"Takeover skipped: branch HEAD moved concurrently ({exc})",
|
|
140
|
+
definitive_no_mutation=True,
|
|
141
|
+
preserves_diff_fingerprint=True,
|
|
142
|
+
)
|
|
143
|
+
logger.error("PR #%d: takeover failed: %s", snapshot.pr_number, exc)
|
|
144
|
+
return ActionResult(
|
|
145
|
+
name=self.name,
|
|
146
|
+
decision=ActionDecision.FAILED,
|
|
147
|
+
error=str(exc),
|
|
148
|
+
details="reclaim_copilot_commit failed",
|
|
149
|
+
)
|
|
128
150
|
if isinstance(exc, ProviderRateLimitError) and exc.is_rate_limit:
|
|
129
151
|
raise
|
|
130
152
|
logger.error("PR #%d: takeover failed: %s", snapshot.pr_number, exc)
|
|
@@ -247,7 +247,7 @@ def _find_recent_diff_preservation_blocker(
|
|
|
247
247
|
"""Return the latest unconsumed trusted diff-preservation blocker payload."""
|
|
248
248
|
|
|
249
249
|
def _parse_blocker(body: str) -> DiffPreservationBlocker | None:
|
|
250
|
-
match = cast(re.Match[str], _DIFF_PRESERVATION_BLOCKER_RE.
|
|
250
|
+
match = cast(re.Match[str], _DIFF_PRESERVATION_BLOCKER_RE.search(body.rstrip("\r\n")))
|
|
251
251
|
encoded = match.group(1)
|
|
252
252
|
padding = "=" * (-len(encoded) % 4)
|
|
253
253
|
try:
|
|
@@ -331,7 +331,7 @@ def _find_recent_diff_preservation_blocker(
|
|
|
331
331
|
(
|
|
332
332
|
comment.id
|
|
333
333
|
for comment in trusted_comments
|
|
334
|
-
if _DIFF_PRESERVATION_BLOCKER_CLEARED_RE.
|
|
334
|
+
if _DIFF_PRESERVATION_BLOCKER_CLEARED_RE.search(comment.body.rstrip("\r\n")) is not None
|
|
335
335
|
),
|
|
336
336
|
default=0,
|
|
337
337
|
)
|
|
@@ -340,7 +340,7 @@ def _find_recent_diff_preservation_blocker(
|
|
|
340
340
|
comment
|
|
341
341
|
for comment in trusted_comments
|
|
342
342
|
if comment.id > latest_cleared_id
|
|
343
|
-
and _DIFF_PRESERVATION_BLOCKER_RE.
|
|
343
|
+
and _DIFF_PRESERVATION_BLOCKER_RE.search(comment.body.rstrip("\r\n")) is not None
|
|
344
344
|
),
|
|
345
345
|
key=lambda comment: comment.id,
|
|
346
346
|
reverse=True,
|
|
@@ -654,18 +654,32 @@ def run_pipeline(
|
|
|
654
654
|
pre_mutation_snapshot.head_sha[:8],
|
|
655
655
|
)
|
|
656
656
|
return False
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
)
|
|
668
|
-
|
|
657
|
+
persisted_in_summary = False
|
|
658
|
+
from agentic_devtools.cli.ci.pipeline.summary import _find_active_summary_comment
|
|
659
|
+
|
|
660
|
+
summary_comment = _find_active_summary_comment(provider, current_snapshot.pr_number)
|
|
661
|
+
if summary_comment is not None:
|
|
662
|
+
summary_id, summary_body = summary_comment
|
|
663
|
+
if _DIFF_PRESERVATION_BLOCKER_PREFIX in summary_body:
|
|
664
|
+
updated_body = _DIFF_PRESERVATION_BLOCKER_RE.sub(marker, summary_body)
|
|
665
|
+
else:
|
|
666
|
+
updated_body = f"{summary_body}\n\n{marker}"
|
|
667
|
+
provider.update_comment(summary_id, updated_body)
|
|
668
|
+
persisted_in_summary = True
|
|
669
|
+
|
|
670
|
+
if not persisted_in_summary:
|
|
671
|
+
try:
|
|
672
|
+
provider.post_comment_as_pr_token(current_snapshot.pr_number, marker)
|
|
673
|
+
except Exception as exc:
|
|
674
|
+
if isinstance(exc, ProviderRateLimitError) and exc.is_rate_limit:
|
|
675
|
+
raise
|
|
676
|
+
logger.warning(
|
|
677
|
+
"PR #%d: Failed to persist diff-preservation blocker for %s: %s",
|
|
678
|
+
current_snapshot.pr_number,
|
|
679
|
+
current_snapshot.head_sha[:8],
|
|
680
|
+
str(exc)[:200],
|
|
681
|
+
)
|
|
682
|
+
return False
|
|
669
683
|
persisted_diff_preservation_allows_file_removal = invalidation_allows_file_removal
|
|
670
684
|
persisted_diff_preservation_allowed_removed_files = tuple(sorted(allowed_removed_files))
|
|
671
685
|
return True
|
|
@@ -699,18 +713,38 @@ def run_pipeline(
|
|
|
699
713
|
live_head_sha[:8],
|
|
700
714
|
)
|
|
701
715
|
return
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
716
|
+
|
|
717
|
+
cleared_in_summary = False
|
|
718
|
+
from agentic_devtools.cli.ci.pipeline.summary import _find_active_summary_comment
|
|
719
|
+
|
|
720
|
+
summary_comment = _find_active_summary_comment(provider, current_snapshot.pr_number)
|
|
721
|
+
if summary_comment is not None and _DIFF_PRESERVATION_BLOCKER_PREFIX in summary_comment[1]:
|
|
722
|
+
summary_id, summary_body = summary_comment
|
|
723
|
+
cleaned_body = _DIFF_PRESERVATION_BLOCKER_RE.sub("", summary_body).rstrip()
|
|
724
|
+
provider.update_comment(summary_id, cleaned_body)
|
|
725
|
+
cleared_in_summary = True
|
|
726
|
+
|
|
727
|
+
# Delete any standalone blocker comments or cleared comments on this PR
|
|
728
|
+
for c in provider.list_issue_comments(current_snapshot.pr_number):
|
|
729
|
+
c_body = (c.body or "").strip()
|
|
730
|
+
if _DIFF_PRESERVATION_BLOCKER_RE.fullmatch(c_body) or _DIFF_PRESERVATION_BLOCKER_CLEARED_RE.fullmatch(
|
|
731
|
+
c_body
|
|
732
|
+
):
|
|
733
|
+
provider.delete_comment(c.id)
|
|
734
|
+
|
|
735
|
+
if not cleared_in_summary:
|
|
736
|
+
marker = f"{_DIFF_PRESERVATION_BLOCKER_CLEARED_PREFIX}{live_head_sha} -->"
|
|
737
|
+
try:
|
|
738
|
+
provider.post_comment_as_pr_token(current_snapshot.pr_number, marker)
|
|
739
|
+
except Exception as exc:
|
|
740
|
+
if isinstance(exc, ProviderRateLimitError) and exc.is_rate_limit:
|
|
741
|
+
raise
|
|
742
|
+
logger.warning(
|
|
743
|
+
"PR #%d: Failed to clear diff-preservation blocker for %s: %s",
|
|
744
|
+
current_snapshot.pr_number,
|
|
745
|
+
current_snapshot.head_sha[:8],
|
|
746
|
+
str(exc)[:200],
|
|
747
|
+
)
|
|
714
748
|
|
|
715
749
|
def _refresh_snapshot_after_invalidation() -> str | None:
|
|
716
750
|
"""Refresh and validate the PR snapshot after a mutating action."""
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
agentic_devtools/__init__.py,sha256=J_Zw_vWKghk-cLmqI83hXQmSiS8zMhGIHM5WPLDkZuo,242
|
|
2
|
-
agentic_devtools/_version.py,sha256=
|
|
2
|
+
agentic_devtools/_version.py,sha256=I-KiN5Y2Z77Y2jSHcRA2j1dCFjS4x-Nm6KJcb1wQCcA,524
|
|
3
3
|
agentic_devtools/agdt_gitignore.py,sha256=vVVqTjBZ_ijn6U3Lnh_JGrARLschYVN-fFal9jDk0Ak,2694
|
|
4
4
|
agentic_devtools/background_tasks.py,sha256=IVC1XJKQzPBP8wCRNCZX_iZCg9FJY_GBUzddSJj7xqw,17473
|
|
5
5
|
agentic_devtools/config.py,sha256=DEVxTVZhsQbVQwO9qdB_1h19aBpjMzF6xJY_ePYLGLs,15629
|
|
@@ -166,7 +166,7 @@ agentic_devtools/cli/ci/dispatch_state.py,sha256=UZOzy4wHMy5Vkp8jJ1QHLSG0m_oLElM
|
|
|
166
166
|
agentic_devtools/cli/ci/due_probe_wakeup.py,sha256=qUSgDbtZ09jytNt6UbCFrwxCoeUObKx6u5W0GQXYeNs,13343
|
|
167
167
|
agentic_devtools/cli/ci/exceptions.py,sha256=zpKWOgnBbHHQgAQRvdRW4VFnE_qdgqgmo8r1H-x47l4,1086
|
|
168
168
|
agentic_devtools/cli/ci/finalization_state.py,sha256=ZJzIypv09jGUYWPS_SwbBkO-OnsW6g83ZC77x51TofY,5123
|
|
169
|
-
agentic_devtools/cli/ci/github_provider.py,sha256=
|
|
169
|
+
agentic_devtools/cli/ci/github_provider.py,sha256=IMAoSn3BqeZnCt1ZaMrAiWa9YtX5kuvSID5Tc5mqqws,347879
|
|
170
170
|
agentic_devtools/cli/ci/guards.py,sha256=hCUTAbQ7JNrAbsDomCRVZA2TQ33tv5fK_FNSmk-9h50,56736
|
|
171
171
|
agentic_devtools/cli/ci/job_logs.py,sha256=du0-DiNGNxyg2J5YwlFPJ0VW9Ib8eNcwzlia0RCd9SY,12810
|
|
172
172
|
agentic_devtools/cli/ci/logging_config.py,sha256=Tw_h8LB709gbMd0WZMATLAPIJ1r_c_nE18Bi4bvldHA,2340
|
|
@@ -201,7 +201,7 @@ agentic_devtools/cli/ci/pipeline/exceptions.py,sha256=4UXy2weeQZex_lp4sILNxlYfGj
|
|
|
201
201
|
agentic_devtools/cli/ci/pipeline/exclusion.py,sha256=mrOG5G1-m3U-GM4YgtMTuzmoj02TXB6GbNxemRoLtV4,931
|
|
202
202
|
agentic_devtools/cli/ci/pipeline/gate_verdict.py,sha256=RSFKCtx3_x81TKucfShVX1SH9fwUOXe_oP3ImPTl6C8,44261
|
|
203
203
|
agentic_devtools/cli/ci/pipeline/models.py,sha256=ih_vkb3xHDUnbY4YLIhtY5-neq4wO4-4o__FEoh8idU,3492
|
|
204
|
-
agentic_devtools/cli/ci/pipeline/runner.py,sha256=
|
|
204
|
+
agentic_devtools/cli/ci/pipeline/runner.py,sha256=OLKLZz9a4ORP35U3BwFa4KCTaIvBe9b2eoTW3z5OXRg,55534
|
|
205
205
|
agentic_devtools/cli/ci/pipeline/session_detector.py,sha256=YaVQa_uqI8GhZ_wtDBzKqzAc5KEoAdoNH9ZeJ0VPcwc,14409
|
|
206
206
|
agentic_devtools/cli/ci/pipeline/snapshot.py,sha256=Rc9WSFrMYBv-R7ikcv5qi9WDCtuClB4wAiAPMtd5IBw,49860
|
|
207
207
|
agentic_devtools/cli/ci/pipeline/suggestions.py,sha256=s2FB-y1gd73R3P_5X2CSQJfZPWO5QFU2jFGYB25ZZuY,26965
|
|
@@ -216,10 +216,10 @@ agentic_devtools/cli/ci/pipeline/actions/guards.py,sha256=UIkTgv5_aKqSVNRFlvl_Ji
|
|
|
216
216
|
agentic_devtools/cli/ci/pipeline/actions/merge.py,sha256=bCOK0HiwpBmGTxYb0Bq8pRVh3dT24HLdW2ThUb-qzSA,19755
|
|
217
217
|
agentic_devtools/cli/ci/pipeline/actions/publish.py,sha256=uodkeHkqAdEu_1HNXfyJhVZFW7TNdsNMFxDyWiM2yGw,5404
|
|
218
218
|
agentic_devtools/cli/ci/pipeline/actions/rebase.py,sha256=SCfgKRS9Pt4Ixg93q6DmA-dnytm0yfz1H9fik66alkQ,5675
|
|
219
|
-
agentic_devtools/cli/ci/pipeline/actions/request_review.py,sha256=
|
|
219
|
+
agentic_devtools/cli/ci/pipeline/actions/request_review.py,sha256=E-WS_7-IxgtpRo-U6IfX6Nc4oGF_b-D_gWha4AbhoLw,10667
|
|
220
220
|
agentic_devtools/cli/ci/pipeline/actions/resolve_threads.py,sha256=25uZ39mk_b3EcIbwYAGcUfAdlrjgq_E-t0taP01KiR8,11005
|
|
221
221
|
agentic_devtools/cli/ci/pipeline/actions/squash.py,sha256=p4gHuxj8DF3o2zXLMVYvlir1sxkMDog3EGj5zqgDP_0,11435
|
|
222
|
-
agentic_devtools/cli/ci/pipeline/actions/takeover.py,sha256=
|
|
222
|
+
agentic_devtools/cli/ci/pipeline/actions/takeover.py,sha256=MjgDw6pwezIQhNzbcsdnz8-NiJj2hI4wMSe-cZEwmgc,7822
|
|
223
223
|
agentic_devtools/cli/ci/pipeline/discovery/__init__.py,sha256=QNdOYvl_wK6qcWOvNJR-wm8EtWD_DPn4barKF5RSmfU,752
|
|
224
224
|
agentic_devtools/cli/ci/pipeline/discovery/browser_strategy.py,sha256=uo1uQ1iX7Aas0S-U5b5dZ6VxVGsBuZ1ThzLjxGRB2_M,4647
|
|
225
225
|
agentic_devtools/cli/ci/pipeline/discovery/graphql_strategy.py,sha256=SoIzfpgX-llezaGmuZt0e4GBhdFoetYAA_ML1EHz20Q,2424
|
|
@@ -1146,8 +1146,8 @@ agentic_devtools/_bundled_skills/skills/run-targeted-checks/SKILL.md,sha256=sZl6
|
|
|
1146
1146
|
agentic_devtools/_bundled_skills/skills/speckit-normalize/SKILL.md,sha256=ZTaiy5pqsfvIyJ-YAfwfoCMf_oeZqTk7oxTUyuOwkeE,5738
|
|
1147
1147
|
agentic_devtools/_bundled_skills/skills/write-github-commit-message/SKILL.md,sha256=Ep1lR8NDN117Iytj172VZgqazFiLpJ56Z7RXgaTnxR8,2626
|
|
1148
1148
|
agentic_devtools/_bundled_skills/skills/write-github-commit-message/commit-types.md,sha256=bTy_t68ZD6R87rFIzq9wybTu8Wudoahb7nB9IWC4bFo,1839
|
|
1149
|
-
agentic_devtools-0.2.
|
|
1150
|
-
agentic_devtools-0.2.
|
|
1151
|
-
agentic_devtools-0.2.
|
|
1152
|
-
agentic_devtools-0.2.
|
|
1153
|
-
agentic_devtools-0.2.
|
|
1149
|
+
agentic_devtools-0.2.512.dist-info/METADATA,sha256=EiIAYG-IogB48NKMd4c-go6K2DqMKYgAJXgVI1nh4T0,34732
|
|
1150
|
+
agentic_devtools-0.2.512.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
|
|
1151
|
+
agentic_devtools-0.2.512.dist-info/entry_points.txt,sha256=MaoqkOpz_sUHbA8Y6ULiFqeI_4V-TNxysWeJFmNBVhM,12911
|
|
1152
|
+
agentic_devtools-0.2.512.dist-info/licenses/LICENSE,sha256=yBEDdICksxhBYLWoERKp9MTqwGnUF6Ryj9BTLwXTc6k,1082
|
|
1153
|
+
agentic_devtools-0.2.512.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|