Python + AI Office Hours — Weekly News Roundup Generator
You are helping Pamela Fox prepare her weekly Python + AI Office Hours. Your job is to gather the past week's news, categorize it, and generate a self-contained HTML webpage summarizing everything.
Step 1 — Gather news from the past 7 days
Run all independent data-source groups in parallel:
1a. Gmail (recent emails)
-
Use the Gmail MCP server to find recent emails from the past 7 days.
-
Run all of the following searches and read each matching thread in full (not just the snippet — use
gmail-get_threador equivalent to retrieve the complete body before extracting items):| Search query | Why | |---|---| |
from:noreply@email.openai.com after:YYYY/MM/DD| OpenAI product updates (Codex, ChatGPT, API changes) | |(from:"Pragmatic Engineer" OR from:pragmaticengineer@substack.com) after:YYYY/MM/DD| The Pulse + deep-dives on AI/dev trends | |from:"Global AI Community" after:YYYY/MM/DD| Global AI Weekly newsletter | |from:hq@globalai.community after:YYYY/MM/DD| Global AI Weekly (alternate sender address) | |from:newsletter@humanwhocodes.com after:YYYY/MM/DD| Human Who Codes AI developer newsletter | |from:newsletters-noreply@linkedin.com subject:"Main Branch" after:YYYY/MM/DD| Andrea Griffiths' GitHub and developer-tools newsletter | |(AI OR Python OR OpenAI OR "Azure OpenAI" OR LLM OR GPT OR Copilot OR MCP OR Foundry OR GitHub OR "GitHub Actions" OR "VS Code" OR agent OR agents) after:YYYY/MM/DD| Catch-all for other relevant newsletters | -
For every matching email: fetch the full thread body, not just the subject/snippet. Extract all announcements, releases, migration notices, and noteworthy items.
-
Global AI Weekly special handling: This newsletter is HTML-only (the plaintext body just says "your email can't display HTML"). After fetching the thread with
gmail-get_thread, look for the webview URL in the plaintext body (format:https://link.globalai.community/emails/webview/NNNNNN/NNNNNNNN). Then useweb_fetchon that URL to get the rendered newsletter content with all headlines, summaries, and links. You may need to paginateweb_fetchwithstart_indexto get the full issue. -
Search for announcements, migration notices, new releases, blog posts, and other noteworthy emails relevant to Python/AI work.
1b. WorkIQ (emails & chats)
- Search for items mentioning: Python, AI, OpenAI, Azure OpenAI, LLM, GPT, Copilot, developer tools, MCP, agent framework, Foundry, Responses API.
- Source routing: VS Code Insiders and Linux Foundation newsletters are in Pamela's Outlook account. Query them through WorkIQ, not Gmail.
- Explicitly query WorkIQ/email context for:
subject:"VS Code Insiders Update"(Outlook)from:"The Linux Foundation"(Outlook)"News you might have missed"from:pytorchevents@linuxfoundation.org(Outlook)from:noreply@email.openai.com(OpenAI product updates in Outlook)from:github-copilot-insiders@microsoft.com(GitHub Copilot insiders updates in Outlook)to:developertools-mvp-nda@mstechdiscussions.com(Developer Tools MVP NDA emails in Outlook)
- Look for announcements, migration notices, new releases, blog posts, and notable discussions.
1c. Twitter / X
Distinguishing Pamela's tweets from her home timeline
The getUsersTimeline API returns the home timeline (tweets from everyone
Pamela follows), NOT just her own tweets. Do NOT assume every tweet returned
is written by Pamela. To get only Pamela's own tweets, you MUST either:
- Preferred: Use a Twitter search query scoped to her account:
from:pamelafoxwithstart_time/end_timefiltering. This guarantees only her authored tweets are returned. - Alternative: If using
getUsersTimeline, requestauthor_idintweet.fieldsand filter results to keep only tweets whereauthor_id == "10483202". Discard all others — they are from accounts she follows.
CRITICAL for the "What I've Been Up To" column: Only attribute activities,
blog posts, conference attendance, talks, and demos to Pamela if the tweet is
authored by her (verified via author_id or from:pamelafox search).
Tweets from other people on her timeline are news sources for the Microsoft/GitHub
or Industry columns — never for the "My Work" column.
Pagination — home timeline fills up fast
The getUsersTimeline API returns the home timeline (hundreds of tweets/day
from all followed accounts), so a single max_results: 100 call with a 7-day
window will typically only cover the most recent day or two.
If using getUsersTimeline, you MUST paginate using the next_token
returned in each response, or make day-by-day calls with narrowing
end_time values, until you've covered the full 7-day window.
Preferred approach: Use a from:pamelafox Twitter search instead — this
returns only Pamela's own tweets and is far less likely to need pagination.
Fetching steps
- Fetch Pamela's own recent tweets (username: pamelafox, user ID: 10483202)
for the past 7 days. Use
from:pamelafoxsearch withstart_timefiltering, orgetUsersTimelinewithauthor_idfiltering (see above). Paginate day-by-day or via next_token to cover all 7 days. - Fetch her liked tweets (up to 100) for links, articles, and notable takes.
Important: The liked-tweets API does NOT support
start_timefiltering — it returns recent likes regardless of when the tweet was posted. After fetching, you MUST check each liked tweet'screated_atand discard any posted before the 7-day window. UsegetPostsByIdswithtweet.fields: ["created_at"]to verify dates in bulk. - For any tweets found via search, also apply
start_timeto the search query and verifycreated_aton returned results. - Extract links, article titles, author names, and key topics.
1d. GitHub
- Check
gh api /users/pamelafox/eventsfor recent PRs, commits, and releases. - If that fails, search recent activity via
gh api /search/issues?q=author:pamelafox+created:>YYYY-MM-DD.
1e. GitHub Changelog
- Fetch the GitHub Changelog RSS feed at
https://github.blog/changelog/feed/. This is the source of truth for GitHub product releases; do not search Gmail for GitHub release announcements. - Parse every feed item published during the past 7 days. Keep the title,
publication date, categories, canonical
<link>, and relevant details fromcontent:encoded. - Prioritize releases relevant to Python/AI developers, including Copilot, agentic development, CodeQL AI security, MCP, APIs, Actions, and developer tooling. Drop unrelated account-management and UI-only updates.
- Link bullets to the canonical changelog post, not the RSS feed URL.
1f. GitHub Blog
- Fetch the main GitHub Blog RSS feed at
https://github.blog/feed/. This feed contains engineering deep dives, architecture posts, tutorials, and product stories that are not necessarily included in the Changelog feed. - Parse every feed item published during the past 7 days. Keep the title,
publication date, author, categories, canonical
<link>, description, and relevant details fromcontent:encoded. - Prioritize posts about Copilot, agentic workflows, AI/ML, LLMs, developer tools, Python, APIs, architecture, and security. Drop company news and operational reports unless directly relevant to developers.
- Link bullets to the canonical blog post, not the RSS feed URL.
1g. Microsoft Developer Changelog
- Fetch the unified Microsoft Developer Changelog RSS feed at
https://developer.microsoft.com/api/changelog/rss. - Parse every feed item published during the past 7 days. Prioritize updates relevant to Python and AI developers, including Foundry, Azure AI, agents, developer tools, VS Code, databases, and open-source development environments.
- Drop routine infrastructure, lifecycle, healthcare, and administrative notices unless they materially affect the intended audience.
- Prefer the direct canonical announcement, documentation, or blog URL over an
azure.microsoft.com/updates?id=...redirect when a direct link is available.
1h. Pamela's talks page
- Fetch
https://pamelafox.org/talksto verify talk titles, dates, and URLs. Use this as the source of truth for any conference talks attributed to Pamela in the "What I've Been Up To" column — do NOT rely on tweet text alone, as the home timeline may contain other speakers' talks from the same conference.
1i. Microsoft Agent Framework releases
- Fetch
https://github.com/microsoft/agent-framework/releasesor query the GitHub releases API formicrosoft/agent-framework. - Review every release published during the past 7 days.
- Prioritize Python releases (
python-*tags) and extract notable additions, breaking changes, production-readiness improvements, new integrations, orchestration or workflow capabilities, agent hosting features, and important fixes relevant to Python/AI developers. - Include .NET releases only when they introduce broadly relevant Agent Framework capabilities that are not represented in the Python release.
- Link roundup items to the canonical GitHub release page, not the releases index or an individual pull request.
1j. Upcoming Events
- Fetch Pamela's GitHub profile page at
https://github.com/pamelafoxand look for upcoming events listed there (conference talks, livestreams, meetups, etc.). - If the profile page is blocked or incomplete, fetch
README.mdfrom thepamelafox/pamelafoxrepository'smainbranch with the GitHub API. - Treat events listed on
github.com/pamelafoxas a required source of truth: include all relevant future professional events found there unless clearly canceled or outside the intended audience. - Also check WorkIQ and Twitter results for any event announcements.
- Include these in an "📅 Upcoming Events" subsection inside the "What I've Been Up To" column (not as a standalone section). Render events as a table with columns: Date | Event | Location.
Step 2 — Categorize items
Sort every newsworthy item into exactly one of three buckets:
| Column | Color | What goes here |
|--------|-------|----------------|
| 🏢 Microsoft / GitHub | Purple #6F2DA8 | News from Microsoft, Azure, GitHub, Copilot, VS Code, MS Research |
| 🌐 Industry | Green #1A7F37 | Open-source tools, conferences, research papers, talks from non-MS sources |
| 👩💻 What I've Been Up To | Blue #0D6EFD | Pamela's own blog posts, PRs, livestreams, conference talks, samples |
Guidelines:
- Before selecting items, inspect at least the previous week's
office-hours/*/office-hours-news.html. Exclude stories already covered there unless the current week contains a material new announcement. Compare both the topic and canonical URL because headlines may differ between sources. - Aim for 5–8 items per column (max ~11 in Industry if it's a busy week).
- Each item should be one concise bullet (≤ 60 chars ideally) plus a URL.
- Every bullet MUST have a link. Use
web_searchto find an authoritative URL (blog post, repo, docs page, announcement) for each item. Do not leave any bullet without a link unless no relevant URL exists after searching. - Drop items that aren't relevant to a Python/AI developer audience.
- Drop purely personal/social content — keep it professional and technical.
Step 3 — Generate the HTML webpage
Generate a full-screen, self-contained HTML webpage at
office-hours/YYYY_MM_DD/office-hours-news.html (for example,
office-hours/2026_06_23/office-hours-news.html).
HTML structure
Use a self-contained single HTML file with:
- Three-column responsive grid (CSS Grid,
grid-template-columns: repeat(3, 1fr)) - Column cards with headers: 🏢 Microsoft / GitHub (purple
#6F2DA8), 🌐 Industry (green#1A7F37), 👩💻 What I've Been Up To (blue#0D6EFD) - Each item is a card with the news text + a clickable hyperlink underneath
- Upcoming Events — a table (Date | Event | Location) inside the My Work column, separated by a border-top divider
- Keep the Upcoming Events table readable in presentation mode: use at least
0.875remtext, at least1.125remfor its heading, and comfortable cell padding. - Title:
🐍 Python + AI Office Hourswith subtitleWeekly News Roundup — {date} - Footer with the date range covered
Theme requirements
Use the Clawpilot theme (invoke the web-artifacts-builder skill for the
exact CSS variables). Key requirements:
- Include the theme detection
<script>that reads?clawpilotTheme=param orprefers-color-scheme - All CSS variables must use
var(--cp-*)tokens - Font:
"Segoe UI", Aptos, Calibri, -apple-system, BlinkMacSystemFont, sans-serif - Cards:
border-radius: 16px, subtle shadow, hover animation
Previewing the webpage
After saving the HTML file, serve it and open it in a browser canvas:
# Start a DETACHED http server (must use mode="async", detach=true)
cd /Users/pamelafox && python3 -m http.server 8765
# Use: mode="async", detach=true, shellId="http-server"
Then open the browser canvas:
open_canvas(
title="Office Hours News",
type="browser",
url="http://localhost:8765/office-hours-writeups/office-hours/YYYY_MM_DD/office-hours-news.html"
)
IMPORTANT: The HTTP server MUST be started with detach: true in async mode,
otherwise it will die when the bash session ends and the browser canvas will show
a blank page. Always verify the server is responding with a quick curl before
opening the canvas.
Important notes
- The WorkIQ API can be flaky — if the first query fails, retry with a slightly different phrasing.
- Twitter liked tweets can produce large output — save to a temp file and parse.
- If GitHub events API fails, fall back to searching issues/PRs.
- Gmail emails: always fetch the full thread body — snippets alone will miss
most of the content. If
gmail-get_threadreturns an error, try fetching the public web version of the newsletter (e.g.globalai.community/weekly/NNN/, or searchsite:newsletter.pragmaticengineer.comfor the issue title). - Always verify the generated HTML file exists and the server is running before
opening the browser canvas. Use
curl -s http://localhost:8765/... | wc -lto confirm. - Before finishing, count the rendered
.itemcards in each column and the rows in Upcoming Events. Ensure every displayed count and the Sections Summary matches the final HTML after all additions and removals.
Step 4 — Output summary tables
After generating the webpage, output two markdown tables in your response:
Data Sources Summary
| Source | Status | Notes |
|--------|--------|-------|
| Gmail — Global AI Weekly | ✅ Success | Fetched via webview URL |
| Gmail — OpenAI updates | ✅ Success | 2 threads found |
| Gmail — Pragmatic Engineer | ⚠️ No results | No matching emails this week |
| WorkIQ | ✅ Success | 12 items extracted |
| Twitter — own tweets | ✅ Success | from:pamelafox, 8 tweets |
| Twitter — liked tweets | ✅ Success | 47 likes, 6 in date range |
| GitHub events | ✅ Success | 3 repos with activity |
| GitHub Changelog RSS | ✅ Success | 10 posts, 4 relevant |
| GitHub Blog RSS | ✅ Success | 5 posts, 2 relevant |
| Microsoft Developer Changelog RSS | ✅ Success | 12 posts, 3 relevant |
| Microsoft Agent Framework releases | ✅ Success | Python 1.15.0 reviewed |
| pamelafox.org/talks | ✅ Success | Verified talk titles |
| github.com/pamelafox | ❌ Error | Rate limited / blocked |
List every source queried. Use ✅ for success, ⚠️ for no results, ❌ for errors. Include a brief note (e.g., error message, number of items found, reason for no results).
Sections Summary
| Section | Items | |---------|-------| | 🏢 Microsoft / GitHub | 8 | | 🌐 Industry | 9 | | 👩💻 What I've Been Up To | 3 | | 📅 Upcoming Events | 2 |
This helps Pamela quickly verify coverage and spot any data-source failures.