Style Analyzer
Analyze the user's communication patterns across Teams and Outlook and build a style profile that other skills or automations (e.g. an out-of-office auto-responder) can use to write in the user's voice. Save the profile to memory so it's available across sessions.
Tool names. This skill refers to Microsoft 365 tools as
m365_*and to memory as remember/recall tools. If your host exposes these under different names, map them to the equivalent capability.
Data collection
1. Gather sent emails (20–30 samples)
- List the last ~30 emails in the Sent folder.
- For emails with real body content (not just meeting accepts/declines), fetch the full text body.
2. Gather Teams chat messages
- List recent chats (~50).
- For each relevant chat (prioritize active 1:1 and group chats), fetch the last ~30 messages.
- Filter to messages from the current user (match the
fromfield to the user's display name).
3. Sample diversity
Aim for:
- 10+ sent emails with body content
- 50+ Teams messages across 20–25 different chats
- A mix of 1:1, group, and meeting chats
- Both internal and external conversations where available
Analysis framework
Analyze the collected messages across these dimensions:
- A. Greetings — how they address people (first name, "Hi [Name]", "Hey", formal titles); patterns by relationship type (internal vs external).
- B. Tone & formality — professional/casual/mixed; direct vs hedging; warmth indicators.
- C. Message length — average sentence count; frequency of one-word replies; when they write longer messages.
- D. Punctuation & grammar — consistency; common typos (e.g. lowercase "i"); emoji usage (none / occasional / frequent).
- E. Sign-offs — email signature style; Teams message endings; closing phrases ("Thanks", "Regards", etc.).
- F. Common phrases — frequently used expressions for agreement ("sounds good", "makes sense"), requests ("can you", "would you mind"), availability, and FYI/context-setting.
- G. Technical communication — how they explain technical concepts; level of detail; hedging vs confidence.
- H. Action patterns — how they delegate, loop others in, and schedule meetings.
Output
1. Display a summary
Present findings as a formatted table:
## Communication Style Profile for [Name]
| Dimension | Pattern |
|-----------|---------|
| Greetings | ... |
| Tone | ... |
| Length | ... |
| Emojis | ... |
| Sign-offs | ... |
| Technical | ... |
### Common phrases
- "..."
- "..."
### Quirks & notes
- ...
2. Save to memory
Store the style guide in memory. Use two entries to stay within any per-fact length limits:
- Entry 1 — greetings, tone, brevity, punctuation, emojis.
- Entry 2 — common phrases, delegation style, technical communication, quirks.
Tag both as a preference so they persist and can be recalled later.
3. Confirm storage
Tell the user:
- The style profile has been saved to memory.
- It can be recalled with a query like "writing style".
- It's available to other assistants and automations that write in their voice.
Usage notes
- Re-run periodically (e.g. quarterly) to keep the profile current.
- Pairs well with an OOO / auto-responder skill that should mimic the user's voice.
Privacy
All analysis happens inside the user's own agent environment against their own Microsoft 365 data. No communication content is sent to any third party. The saved profile describes how the user writes, not what they wrote — do not store verbatim private message content in the profile.
Run this — do not improvise
This capability's deterministic implementation is a RAPP single-file agent, linked beside this file as style_analyzer_agent.py and embedded as the fenced Python below (sha256 3cb0e67c9a1ad1bd…; 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 style_analyzer_agent.py first:
python3 style_analyzer_agent.py '{"key": "value"}' # arguments as one JSON object
echo '{"key": "value"}' | python3 style_analyzer_agent.py # or on stdin
python3 style_analyzer_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.
"""StyleAnalyzer -- Analyze the user's communication style across their Teams chats and emails to build a reusable mimicry profile — greetings, tone, length, punctuation, sign-offs, common phrases, and quirks. Use this skill when the user asks to capture or analyze their writing style, or before configuring an assistant (e.g. an OOO auto-responder) that should write in their voice.
Generated by the rapp skill from style-analyzer. 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 = '# Style Analyzer\n\nAnalyze the user's communication patterns across Teams and Outlook and build a\nstyle profile that other skills or automations (e.g. an out-of-office\nauto-responder) can use to write in the user's voice. Save the profile to memory\nso it's available across sessions.\n\n> **Tool names.** This skill refers to Microsoft 365 tools as `m365_*` and to\n> memory as remember/recall tools. If your host exposes these under different\n> names, map them to the equivalent capability.\n\n## Data collection\n\n### 1. Gather sent emails (20–30 samples)\n\n- List the last ~30 emails in the **Sent** folder.\n- For emails with real body content (not just meeting accepts/declines), fetch\n the full text body.\n\n### 2. Gather Teams chat messages\n\n- List recent chats (~50).\n- For each relevant chat (prioritize active 1:1 and group chats), fetch the last\n ~30 messages.\n- Filter to messages **from the current user** (match the `from` field to the\n user's display name).\n\n### 3. Sample diversity\n\nAim for:\n\n- 10+ sent emails with body content\n- 50+ Teams messages across **20–25 different chats**\n- A mix of 1:1, group, and meeting chats\n- Both internal and external conversations where available\n\n## Analysis framework\n\nAnalyze the collected messages across these dimensions:\n\n- **A. Greetings** — how they address people (first name, "Hi [Name]", "Hey",\n formal titles); patterns by relationship type (internal vs external).\n- **B. Tone & formality** — professional/casual/mixed; direct vs hedging; warmth\n indicators.\n- **C. Message length** — average sentence count; frequency of one-word replies;\n when they write longer messages.\n- **D. Punctuation & grammar** — consistency; common typos (e.g. lowercase "i");\n emoji usage (none / occasional / frequent).\n- **E. Sign-offs** — email signature style; Teams message endings; closing\n phrases ("Thanks", "Regards", etc.).\n- **F. Common phrases** — frequently used expressions for agreement ("sounds\n good", "makes sense"), requests ("can you", "would you mind"), availability,\n and FYI/context-setting.\n- **G. Technical communication** — how they explain technical concepts; level of\n detail; hedging vs confidence.\n- **H. Action patterns** — how they delegate, loop others in, and schedule\n meetings.\n\n## Output\n\n### 1. Display a summary\n\nPresent findings as a formatted table:\n\n```markdown\n## Communication Style Profile for [Name]\n\n| Dimension | Pattern |\n|-----------|---------|\n| Greetings | ... |\n| Tone | ... |\n| Length | ... |\n| Emojis | ... |\n| Sign-offs | ... |\n| Technical | ... |\n\n### Common phrases\n- "..."\n- "..."\n\n### Quirks & notes\n- ...\n```\n\n### 2. Save to memory\n\nStore the style guide in memory. Use two entries to stay within any per-fact\nlength limits:\n\n- **Entry 1** — greetings, tone, brevity, punctuation, emojis.\n- **Entry 2** — common phrases, delegation style, technical communication,\n quirks.\n\nTag both as a preference so they persist and can be recalled later.\n\n### 3. Confirm storage\n\nTell the user:\n\n- The style profile has been saved to memory.\n- It can be recalled with a query like "writing style".\n- It's available to other assistants and automations that write in their voice.\n\n## Usage notes\n\n- Re-run periodically (e.g. quarterly) to keep the profile current.\n- Pairs well with an OOO / auto-responder skill that should mimic the user's\n voice.\n\n## Privacy\n\nAll analysis happens inside the user's own agent environment against their own\nMicrosoft 365 data. No communication content is sent to any third party. The\nsaved profile describes *how* the user writes, not *what* they wrote — do not\nstore verbatim private message content in the profile.'
# Ordered commands lifted verbatim from the capability's own documentation.
STEPS = []
class StyleAnalyzerAgent(BasicAgent):
def __init__(self):
self.name = 'StyleAnalyzer'
self.metadata = {
"name": "StyleAnalyzer",
"description": "Analyze the user's communication style across their Teams chats and emails to build a reusable mimicry profile \u2014 greetings, tone, length, punctuation, sign-offs, common phrases, and quirks. Use this skill when the user asks to capture or analyze their writing style, or before configuring an assistant (e.g. an OOO auto-responder) that should write in their voice.",
"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 style_analyzer_agent.py
# python3 style_analyzer_agent.py '{"arg": "value"}'
# python3 style_analyzer_agent.py --tool # emit the JSON tool contract
_a = sys.argv[1:]
if _a and _a[0] == "--tool":
print(json.dumps(StyleAnalyzerAgent().to_tool(), indent=2))
else:
_raw = _a[0] if _a else (sys.stdin.read().strip() or "{}")
print(StyleAnalyzerAgent().perform(**json.loads(_raw)))
# rci-capsule:v1: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