Skip to content

Fix upstream watch grouping and refresh AI skills#471

Merged
KSemenenko merged 2 commits intomainfrom
codex/fix-upstream-watch-grouping
Mar 28, 2026
Merged

Fix upstream watch grouping and refresh AI skills#471
KSemenenko merged 2 commits intomainfrom
codex/fix-upstream-watch-grouping

Conversation

@KSemenenko
Copy link
Copy Markdown
Member

Summary\n- paginate upstream issue discovery and group related watch updates into one open issue per skill set\n- repair dead Agent Framework workflow watch URLs and refresh the upstream baseline state\n- update the Agent Framework, Microsoft.Extensions.AI, and MCP skills for the latest official docs\n\n## Validation\n- python3 -m py_compile scripts/upstream_watch.py scripts/generate_catalog.py\n- python3 scripts/upstream_watch.py --validate-config\n- python3 scripts/upstream_watch.py --sync-state-only\n- python3 scripts/upstream_watch.py --dry-run\n- python3 scripts/generate_catalog.py --validate-only

Paginate upstream issue discovery, roll related watches into one open issue per skill group, repair dead Agent Framework watch URLs, and refresh the upstream baseline state. Update the Agent Framework, Microsoft.Extensions.AI, and MCP skills for the latest official documentation changes.

Closes #60

Closes #61

Closes #399

Closes #400

Closes #401

Closes #402

Closes #403

Closes #404

Closes #405

Closes #406

Closes #408

Closes #409

Closes #410

Closes #426

Closes #436

Closes #440

Closes #441

Closes #470
Regenerate .github/upstream-watch-state.json after rebasing the upstream-watch grouping fix onto origin/main and syncing the current upstream baseline.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates upstream-watch automation to deduplicate related upstream changes into a single open issue per library/skill group (with pagination), and refreshes .NET AI-related skills and watch configuration to align with current official documentation sources.

Changes:

  • Group upstream-watch issue creation/update by skill group (issue_key) and paginate open-issue discovery; normalize/repair existing open upstream-watch issues.
  • Refresh Agent Framework watch URLs to Microsoft Learn and update upstream baseline state snapshots.
  • Update dotnet-microsoft-agent-framework, dotnet-microsoft-extensions-ai, and dotnet-mcp skill docs (including version bumps) for the latest official guidance.

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
skills/dotnet-microsoft-extensions-ai/SKILL.md Updates skill guidance and bumps version to reflect new .NET AI surface areas (image generation, local models, MCP quickstarts).
skills/dotnet-microsoft-agent-framework/SKILL.md Updates skill workflow/architecture notes (workflows-as-agent, declarative workflows) and bumps version.
skills/dotnet-mcp/SKILL.md Updates MCP skill guidance and bumps patch version (quickstarts/registry publishing positioning).
scripts/upstream_watch.py Implements grouped issue keys/names, payload markers, pagination, reconciliation/closure of duplicates, and grouped upsert behavior.
README.md Documents that upstream-watch now rolls multiple watches into one grouped upstream issue per library/skill set.
CONTRIBUTING.md Clarifies grouped issue deduplication behavior for upstream-watch config authors.
AGENTS.md Adds repo-wide upstream-watch rules: grouping, updating existing issues, and paginating issue discovery.
.github/upstream-watch.ai.json Repairs Agent Framework watch sources to current Microsoft Learn URLs.
.github/upstream-watch-state.json Refreshes machine-maintained upstream baseline values (ETags/titles/last-modified/releases).

Comment on lines +572 to +573
if issue_key_match and payload and isinstance(payload.get("watches"), dict):
issue_key = issue_key_match.group("issue_key")
Copy link

Copilot AI Mar 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parse_open_issue requires both the issue-key marker and a decodable payload before it will treat an issue as a grouped upstream-watch issue. Since the payload already includes issue_key, this means an issue can be silently ignored (and duplicates re-created) if the issue-key marker is missing/edited while the payload is still valid. Consider trusting payload['issue_key'] when present and (optionally) validating it against the marker when both exist.

Suggested change
if issue_key_match and payload and isinstance(payload.get("watches"), dict):
issue_key = issue_key_match.group("issue_key")
if payload and isinstance(payload.get("watches"), dict):
payload_issue_key = payload.get("issue_key")
marker_issue_key = issue_key_match.group("issue_key") if issue_key_match else None
issue_key: str | None = None
if isinstance(payload_issue_key, str) and payload_issue_key:
# Prefer the issue key from the payload, but validate against the marker when present.
if marker_issue_key and marker_issue_key != payload_issue_key:
# Inconsistent metadata; fall back to legacy parsing for safety.
return parse_legacy_issue(
body=body,
watch_index=watch_index,
state_watches=state_watches,
)
issue_key = payload_issue_key
elif marker_issue_key:
# No usable issue_key in the payload; fall back to the marker if available.
issue_key = marker_issue_key
if not issue_key:
# Cannot determine a reliable issue key; treat as legacy.
return parse_legacy_issue(body=body, watch_index=watch_index, state_watches=state_watches)

Copilot uses AI. Check for mistakes.
return None

try:
decoded = base64.urlsafe_b64decode(match.group("payload").encode("ascii"))
Copy link

Copilot AI Mar 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

decode_issue_payload calls base64.urlsafe_b64decode directly on the marker contents. If the payload ever loses base64 padding (for example via manual edits/copying), urlsafe_b64decode raises Incorrect padding, causing the issue to be treated as legacy/unknown and potentially breaking deduplication. Consider normalizing padding before decoding (or storing/encoding the payload in a way that is resilient to missing padding).

Suggested change
decoded = base64.urlsafe_b64decode(match.group("payload").encode("ascii"))
payload_b64 = match.group("payload")
# Normalize base64 padding to be resilient to missing '=' characters.
padding = "=" * (-len(payload_b64) % 4)
decoded = base64.urlsafe_b64decode((payload_b64 + padding).encode("ascii"))

Copilot uses AI. Check for mistakes.

snapshot = minimal_snapshot(state_watches.get(watch_id, {}))
if not snapshot:
snapshot = {"value": VALUE_MARKER_RE.search(body).group("value")} if VALUE_MARKER_RE.search(body) else {}
Copy link

Copilot AI Mar 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parse_legacy_issue calls VALUE_MARKER_RE.search(body) twice in the same expression, doing the regex work twice and making it harder to read. Capture the match once and reuse it when building the fallback snapshot.

Suggested change
snapshot = {"value": VALUE_MARKER_RE.search(body).group("value")} if VALUE_MARKER_RE.search(body) else {}
value_match = VALUE_MARKER_RE.search(body)
snapshot = {"value": value_match.group("value")} if value_match else {}

Copilot uses AI. Check for mistakes.
@KSemenenko KSemenenko merged commit 2558622 into main Mar 28, 2026
11 checks passed
@KSemenenko KSemenenko deleted the codex/fix-upstream-watch-grouping branch March 29, 2026 15:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants