From 7f2bf68308dd06f58f5a175eaca6773725e96e76 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Fri, 21 Aug 2026 19:14:53 -0700 Subject: [PATCH] Inspired by Energy: evidence-based voice calibration for inbox-triage reply drafts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Energy's cross-app reply agent analyzes ~100 of the user's past replies before drafting, so drafts land in the user's actual voice instead of generic-professional AI register. Port the mechanism into the email-inbox-triage skill's drafting step: - Step 4 now calibrates on a bounded sample (20-50) of the user's own sent replies — greeting/sign-off habits, length, formality, rhythm, per-audience differences, how the user pushes back — before drafting, with an explicit fallback when Sent is empty or inaccessible. - New pitfall + verification item pinning the calibration discipline. - Test locks the evidence-based calibration and fallback language. --- skills/email/email-inbox-triage/SKILL.md | 10 +++++++--- tests/skills/test_email_inbox_triage_skill.py | 10 ++++++++++ .../skills/bundled/email/email-email-inbox-triage.md | 12 ++++++++---- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/skills/email/email-inbox-triage/SKILL.md b/skills/email/email-inbox-triage/SKILL.md index f35cb4e4e8..2aefee45e2 100644 --- a/skills/email/email-inbox-triage/SKILL.md +++ b/skills/email/email-inbox-triage/SKILL.md @@ -1,7 +1,7 @@ --- name: email-inbox-triage description: "Triage an inbox: prioritize threads, draft replies safely." -version: 0.1.0 +version: 0.2.0 author: Ben Barclay (benbarclay), Hermes Agent license: MIT platforms: [linux, macos, windows] @@ -50,9 +50,11 @@ Use these dispositions: Extract sender request, deadline, commitments already made, attachments, and missing information. Done when every surfaced thread has a disposition and a stated reason. -### 4. Draft replies in thread context +### 4. Calibrate the user's voice, then draft replies in thread context -Answer every material question, preserve the user's tone, avoid invented commitments, and state uncertainty. Resolve attachment/link facts before referencing them. Done when each sentence can be checked against the thread or an explicit user preference. +Before drafting the first reply of a run, calibrate on evidence rather than guessing tone (inspired by Energy's reply agent, which studies ~100 of the user's past replies before writing): pull a bounded sample of the user's own recent sent replies from the Sent folder — 20-50 where available, preferring replies to the same recipients or thread types being drafted. Extract the observable style facts: greeting and sign-off habits (and per-audience differences), typical reply length, formality and warmth, sentence rhythm, emoji/exclamation use, and how the user says no or pushes back. Keep the calibration as working notes for this run; if the Sent folder is empty or inaccessible, say so and fall back to matching the incoming thread's register. + +Then draft: answer every material question, match the calibrated voice (not a generic-professional one), avoid invented commitments, and state uncertainty. Resolve attachment/link facts before referencing them. Done when each sentence can be checked against the thread or an explicit user preference, and each draft's tone can be traced to the calibration notes. ### 5. Present an approval batch @@ -75,6 +77,7 @@ Send, label, archive, or create follow-ups only within approval. For ambiguous s - Treating unread as synonymous with important. - Missing earlier unanswered questions in a long thread. +- Drafting in a generic-professional voice instead of calibrating against the user's own sent replies. - Retrying after SMTP succeeded but save-to-Sent failed, causing duplicate mail. - Claiming inbox zero when pagination or another folder was omitted. @@ -82,6 +85,7 @@ Send, label, archive, or create follow-ups only within approval. For ambiguous s - [ ] The requested folders and time window were fully covered, or gaps are stated. - [ ] Every disposition has a reason traceable to thread content. +- [ ] Drafts were calibrated against the user's sent replies, or the fallback was stated. - [ ] No send/delete/archive happened outside the approved batch. - [ ] Every approved mutation was read back from the provider. - [ ] The final response separates completed actions, drafts awaiting approval, and blockers. diff --git a/tests/skills/test_email_inbox_triage_skill.py b/tests/skills/test_email_inbox_triage_skill.py index 7298b0aecc..634537dfbe 100644 --- a/tests/skills/test_email_inbox_triage_skill.py +++ b/tests/skills/test_email_inbox_triage_skill.py @@ -87,3 +87,13 @@ def test_mutation_boundary_is_default_safe(): _, body = _frontmatter_and_body() assert "read + draft" in body, "scope step must default to read+draft, not send/delete" assert "does not imply permission" in body + + +def test_voice_calibration_is_evidence_based(): + """Drafting must calibrate against the user's own sent replies (Energy-inspired), + with an explicit fallback when the Sent folder is unavailable.""" + _, body = _frontmatter_and_body() + assert "Calibrate the user's voice" in body + assert "sent replies" in body.lower() + assert "fall back to matching the incoming thread's register" in body + assert "generic-professional" in body diff --git a/website/docs/user-guide/skills/bundled/email/email-email-inbox-triage.md b/website/docs/user-guide/skills/bundled/email/email-email-inbox-triage.md index 3c68833eec..dfb79508a5 100644 --- a/website/docs/user-guide/skills/bundled/email/email-email-inbox-triage.md +++ b/website/docs/user-guide/skills/bundled/email/email-email-inbox-triage.md @@ -15,8 +15,8 @@ Triage an inbox: prioritize threads, draft replies safely. | | | |---|---| | Source | Bundled (installed by default) | -| Path | `skills/email\email-inbox-triage` | -| Version | `0.1.0` | +| Path | `skills/email/email-inbox-triage` | +| Version | `0.2.0` | | Author | Ben Barclay (benbarclay), Hermes Agent | | License | MIT | | Platforms | linux, macos, windows | @@ -68,9 +68,11 @@ Use these dispositions: Extract sender request, deadline, commitments already made, attachments, and missing information. Done when every surfaced thread has a disposition and a stated reason. -### 4. Draft replies in thread context +### 4. Calibrate the user's voice, then draft replies in thread context -Answer every material question, preserve the user's tone, avoid invented commitments, and state uncertainty. Resolve attachment/link facts before referencing them. Done when each sentence can be checked against the thread or an explicit user preference. +Before drafting the first reply of a run, calibrate on evidence rather than guessing tone (inspired by Energy's reply agent, which studies ~100 of the user's past replies before writing): pull a bounded sample of the user's own recent sent replies from the Sent folder — 20-50 where available, preferring replies to the same recipients or thread types being drafted. Extract the observable style facts: greeting and sign-off habits (and per-audience differences), typical reply length, formality and warmth, sentence rhythm, emoji/exclamation use, and how the user says no or pushes back. Keep the calibration as working notes for this run; if the Sent folder is empty or inaccessible, say so and fall back to matching the incoming thread's register. + +Then draft: answer every material question, match the calibrated voice (not a generic-professional one), avoid invented commitments, and state uncertainty. Resolve attachment/link facts before referencing them. Done when each sentence can be checked against the thread or an explicit user preference, and each draft's tone can be traced to the calibration notes. ### 5. Present an approval batch @@ -93,6 +95,7 @@ Send, label, archive, or create follow-ups only within approval. For ambiguous s - Treating unread as synonymous with important. - Missing earlier unanswered questions in a long thread. +- Drafting in a generic-professional voice instead of calibrating against the user's own sent replies. - Retrying after SMTP succeeded but save-to-Sent failed, causing duplicate mail. - Claiming inbox zero when pagination or another folder was omitted. @@ -100,6 +103,7 @@ Send, label, archive, or create follow-ups only within approval. For ambiguous s - [ ] The requested folders and time window were fully covered, or gaps are stated. - [ ] Every disposition has a reason traceable to thread content. +- [ ] Drafts were calibrated against the user's sent replies, or the fallback was stated. - [ ] No send/delete/archive happened outside the approved batch. - [ ] Every approved mutation was read back from the provider. - [ ] The final response separates completed actions, drafts awaiting approval, and blockers.