Pattern Radar
Find recurring patterns in the user's recent work signals that could be turned into leverage — a blog post (the user keeps explaining the same thing) or an automation (the user keeps doing the same manual, multi-step task). Give blog and automation candidates equal weight; bias toward automation candidates, since offloading repetitive work is usually the bigger win.
Default lookback window: the last 7 days from the current date/time. Treat the provided current datetime as authoritative — never reason from training-data dates.
Tool names. This skill refers to Microsoft 365 tools as
m365_*. If your host exposes them under different names, map them to the equivalent capability.
Inputs — collect breadth, not depth
- Email — list Inbox and Sent from the last 7 days (subjects + first-line previews only; do not open bodies). Pay special attention to Sent items: they reveal the user's own repeated outbound actions (forwards, intros, status pings, FYIs, "looping in X" handoffs, RSVPs, reschedules).
- Active chats — list recent chats; for each chat the user has posted in over the last ~30 days, fetch the last 7 days of messages. Strip @-mention noise.
- Active channels — for channels the user has posted in over the last ~30 days, fetch the last 7 days of messages. Skip silent channels.
- Calendar — list events from the last 7 days (subjects only — no bodies, no attendee lists). Look for repeated reschedules, repeated tentative responses, recurring conflict patterns, and meeting-prep cadences.
Clustering — what counts as a pattern
A signal qualifies only if it appears ≥3 times across ≥2 distinct people / chats / customers / threads / events in the window. Be ruthless — one-offs are noise.
Blog cluster types
- Repeated explanation — the user answers the same question or explains the same concept to 3+ different people. → blog candidate.
- Recurring FAQ — the same question shows up in 3+ chats/channels from different askers. → blog / FAQ candidate.
Automation cluster types (cast a wide net)
- Repeated multi-step manual task — the same sequence of clicks / drafts / file moves / API calls, repeatedly. → automation candidate.
- Repeated handoff / triage — forwarding, "looping in", or intro'ing the same kinds of items to the same people 3+ times. → auto-route by rule or classifier.
- Repeated status pings / FYIs — the same kind of update to the same audience on a cadence. → scheduled digest.
- Repeated meeting reschedules for the same root cause. → auto-propose alternates.
- Repeated RSVPs / tentative responses to recurring meetings with consistent reasoning. → auto-respond by rule.
- Repeated meeting prep — gathering the same context before recurring meetings. → pre-meeting brief.
- Repeated doc/wiki updates — manually appending the same kind of content on a cadence. → scheduled ingest.
- Repeated approvals / sign-offs of the same class of request. → rule-based pre-screen.
- Repeated file/data shuttling — move/rename/reformat between systems. → pipeline.
- Repeated drafting — near-identical emails/messages (welcome notes, onboarding intros, availability, "I have a conflict" replies, follow-ups). → template + auto-fill.
Anti-patterns — do NOT surface
- Normal recurring meeting cadence (standups, weekly syncs) UNLESS there's repetitive manual work around them that could be automated.
- Anything needing the body of an excluded/private email to reason about.
- Automations the user already runs.
Output
List 0–3 candidates max. If signal is thin (< 3 reinforcing data points
across all clusters), output: ✅ No new patterns this run.
Prefer a mix — include at least one automation candidate when one qualifies, even if a blog candidate is stronger.
Per candidate (≤3 lines each):
💡 **<theme in 5–8 words>**
_evidence:_ <1–2 anonymized signals, e.g. "forwarded 4 customer asks to the
same engineer this week" or "explained X to 4 different people in chats">
**<blog|automation>** · <1-line rationale. For automation, name the trigger
and the action, e.g. "trigger: incoming request → action: auto-route + draft
reply".>
Privacy & guardrails
- Read-only. Never send any email, chat, channel reply, or Teams message from this skill. Producing the report is the only output.
- Anonymize. Never include customer/team names, attendee names, meeting times/locations, file paths, or full subjects containing customer identifiers. Say "3 different customers", not the actual names.
- Respect exclusions. Never open or paraphrase content the user has marked as private or excluded (e.g. performance-review or confidential emails).
- When in doubt that a candidate is a real pattern vs. coincidence, drop it — silence is safer than noise.
Run this — do not improvise
This capability's deterministic implementation is a RAPP single-file agent, linked beside this file as pattern_radar_agent.py and embedded as the fenced Python below (sha256 c94dc99e397fadd5…; a byte-exact copy is also vaulted in the capsule comment at the end of this file). On a host with sandbox execution, run the linked file directly — if it is missing, write the fence contents verbatim to pattern_radar_agent.py first:
python3 pattern_radar_agent.py '{"key": "value"}' # arguments as one JSON object
echo '{"key": "value"}' | python3 pattern_radar_agent.py # or on stdin
python3 pattern_radar_agent.py --tool # emit the JSON tool contract
Treat stdout as a tool result. If it reports missing or unresolved inputs, stop and collect them. If it returns steps, execute those steps in order exactly as returned; if it returns instructions, follow them with the supplied inputs. Otherwise use the result verbatim. Do not invent behavior beyond that output. On a host without code execution, treat the Parameters schema and the code below as the exact specification and never paraphrase a step. Never edit inside the generated markers; a converter-equipped host can instead restore the original file checksum-verified with the installed rapp-agent-converter/scripts/toast.py convert SKILL.md --to agent.
"""PatternRadar -- Scan the user's recent Microsoft 365 signals (emails, active chats/channels, calendar subjects) to surface recurring patterns worth productizing — either as a blog post (the user explains the same thing repeatedly) or as an automation (the user does the same multi-step task repeatedly). Use when the user asks "what should I write about?", "what could I automate?", "find patterns in my work", or invokes "/pattern-radar".
Generated by the rapp skill from pattern-radar. The RCI capsule at the bottom of this file carries the full original; `toast.py convert` restores it byte-exact."""
import json
import re
import sys
try:
from agents.basic_agent import BasicAgent
except ImportError: # running OUTSIDE a brainstem -- stay executable anyway.
class BasicAgent: # noqa: D101 - minimal stand-in, same contract
def __init__(self, name=None, metadata=None):
if name:
self.name = name
if metadata:
self.metadata = metadata
def perform(self, **kwargs):
return "Not implemented."
def system_context(self):
return None
def to_tool(self):
return {"type": "function", "function": {
"name": self.name,
"description": self.metadata.get("description", ""),
"parameters": self.metadata.get("parameters", {})}}
# The procedural layer, verbatim from the source capability.
INSTRUCTIONS = '# Pattern Radar\n\nFind recurring patterns in the user's recent work signals that could be turned\ninto leverage — a **blog post** (the user keeps explaining the same thing) or an\n**automation** (the user keeps doing the same manual, multi-step task). Give\nblog and automation candidates equal weight; bias toward automation candidates,\nsince offloading repetitive work is usually the bigger win.\n\nDefault lookback window: **the last 7 days** from the current date/time. Treat\nthe provided current datetime as authoritative — never reason from training-data\ndates.\n\n> **Tool names.** This skill refers to Microsoft 365 tools as `m365_*`. If your\n> host exposes them under different names, map them to the equivalent capability.\n\n## Inputs — collect breadth, not depth\n\n1. **Email** — list Inbox and Sent from the last 7 days (subjects + first-line\n previews only; do not open bodies). **Pay special attention to Sent items**:\n they reveal the user's own repeated outbound actions (forwards, intros, status\n pings, FYIs, "looping in X" handoffs, RSVPs, reschedules).\n2. **Active chats** — list recent chats; for each chat the user has posted in\n over the last ~30 days, fetch the last 7 days of messages. Strip @-mention\n noise.\n3. **Active channels** — for channels the user has posted in over the last ~30\n days, fetch the last 7 days of messages. Skip silent channels.\n4. **Calendar** — list events from the last 7 days (**subjects only** — no\n bodies, no attendee lists). Look for repeated reschedules, repeated tentative\n responses, recurring conflict patterns, and meeting-prep cadences.\n\n## Clustering — what counts as a pattern\n\nA signal qualifies only if it appears **≥3 times across ≥2 distinct people /\nchats / customers / threads / events** in the window. Be ruthless — one-offs are\nnoise.\n\n**Blog cluster types**\n\n- **Repeated explanation** — the user answers the same question or explains the\n same concept to 3+ different people. → blog candidate.\n- **Recurring FAQ** — the same question shows up in 3+ chats/channels from\n different askers. → blog / FAQ candidate.\n\n**Automation cluster types (cast a wide net)**\n\n- **Repeated multi-step manual task** — the same sequence of clicks / drafts /\n file moves / API calls, repeatedly. → automation candidate.\n- **Repeated handoff / triage** — forwarding, "looping in", or intro'ing the\n same kinds of items to the same people 3+ times. → auto-route by rule or\n classifier.\n- **Repeated status pings / FYIs** — the same kind of update to the same audience\n on a cadence. → scheduled digest.\n- **Repeated meeting reschedules** for the same root cause. → auto-propose\n alternates.\n- **Repeated RSVPs / tentative responses** to recurring meetings with consistent\n reasoning. → auto-respond by rule.\n- **Repeated meeting prep** — gathering the same context before recurring\n meetings. → pre-meeting brief.\n- **Repeated doc/wiki updates** — manually appending the same kind of content on\n a cadence. → scheduled ingest.\n- **Repeated approvals / sign-offs** of the same class of request. → rule-based\n pre-screen.\n- **Repeated file/data shuttling** — move/rename/reformat between systems. →\n pipeline.\n- **Repeated drafting** — near-identical emails/messages (welcome notes,\n onboarding intros, availability, "I have a conflict" replies, follow-ups). →\n template + auto-fill.\n\n**Anti-patterns — do NOT surface**\n\n- Normal recurring meeting cadence (standups, weekly syncs) UNLESS there's\n repetitive *manual* work around them that could be automated.\n- Anything needing the body of an excluded/private email to reason about.\n- Automations the user already runs.\n\n## Output\n\nList **0–3 candidates max**. If signal is thin (< 3 reinforcing data points\nacross all clusters), output: `✅ No new patterns this run.`\n\nPrefer a **mix** — include at least one automation candidate when one qualifies,\neven if a blog candidate is stronger.\n\nPer candidate (≤3 lines each):\n\n```\n💡 **<theme in 5–8 words>**\n _evidence:_ <1–2 anonymized signals, e.g. "forwarded 4 customer asks to the\n same engineer this week" or "explained X to 4 different people in chats">\n **<blog|automation>** · <1-line rationale. For automation, name the trigger\n and the action, e.g. "trigger: incoming request → action: auto-route + draft\n reply".>\n```\n\n## Privacy & guardrails\n\n- **Read-only.** Never send any email, chat, channel reply, or Teams message from\n this skill. Producing the report is the only output.\n- **Anonymize.** Never include customer/team names, attendee names, meeting\n times/locations, file paths, or full subjects containing customer identifiers.\n Say "3 different customers", not the actual names.\n- **Respect exclusions.** Never open or paraphrase content the user has marked as\n private or excluded (e.g. performance-review or confidential emails).\n- When in doubt that a candidate is a real pattern vs. coincidence, drop it —\n silence is safer than noise.'
# Ordered commands lifted verbatim from the capability's own documentation.
STEPS = []
class PatternRadarAgent(BasicAgent):
def __init__(self):
self.name = 'PatternRadar'
self.metadata = {
"name": "PatternRadar",
"description": "Scan the user's recent Microsoft 365 signals (emails, active chats/channels, calendar subjects) to surface recurring patterns worth productizing \u2014 either as a blog post (the user explains the same thing repeatedly) or as an automation (the user does the same multi-step task repeatedly). Use when the user asks \"what should I write about?\", \"what could I automate?\", \"find patterns in my work\", or invokes \"/pattern-radar\".",
"parameters": {
"type": "object",
"properties": {},
"required": []
}
}
super().__init__(name=self.name, metadata=self.metadata)
def perform(self, **kwargs): # toaster:generated-perform
return json.dumps({"status": "ok", "instructions": INSTRUCTIONS,
"inputs": kwargs,
"note": "Prose-only capability: follow INSTRUCTIONS "
"with the given inputs."}, indent=2)
if __name__ == "__main__":
# echo '{"arg": "value"}' | python3 pattern_radar_agent.py
# python3 pattern_radar_agent.py '{"arg": "value"}'
# python3 pattern_radar_agent.py --tool # emit the JSON tool contract
_a = sys.argv[1:]
if _a and _a[0] == "--tool":
print(json.dumps(PatternRadarAgent().to_tool(), indent=2))
else:
_raw = _a[0] if _a else (sys.stdin.read().strip() or "{}")
print(PatternRadarAgent().perform(**json.loads(_raw)))
# rci-capsule:v1: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