Draft email responses by pulling context from Gmail through PersonalDataHub
Given a natural language email request, pull relevant data from connected sources through PersonalDataHub, analyze the context, and draft a response.
Read ~/.pdh/config.json to get the hubUrl. If the file doesn't exist, tell the user to run npx pdh init and npx pdh start first.
Run curl -s <hubUrl>/health via Bash. If it fails, tell the user to start the server with npx pdh start.
Analyze the user's message to identify:
Before searching, plan which queries to run and in what order. Think about:
Example strategy for "I've been discussing a proposal with Diego@UCSF, we mentioned law school candidates":
from:diego + to:diego — all recent correspondence with Diegodiego proposal — emails mentioning both Diego and proposaldiego "law school" — emails mentioning law school in the Diego thread"law school" professor candidate — broader search for candidate discussionsPull data from PersonalDataHub using the REST API. Make parallel calls when queries are independent:
curl -s -X POST <hubUrl>/app/v1/pull \
-H "Content-Type: application/json" \
-d '{"source": "gmail", "query": "<query>", "limit": 20, "purpose": "<why>"}'
Query syntax (Gmail):
from:diego / to:diego — by sender/recipientsubject:proposal — keyword in subject"law school" — exact phrasenewer_than:90d / older_than:7d — time rangeshas:attachment — emails with attachmentsfrom:diego subject:proposal newer_than:90dCross-source pulls: For non-email sources, change the source field:
curl -s -X POST <hubUrl>/app/v1/pull \
-H "Content-Type: application/json" \
-d '{"source": "github", "query": "<query>", "limit": 10, "purpose": "<why>"}'
Guidelines:
source_item_id — the same email may appear in multiple query results.purpose for each.Review results from all queries and all sources. Extract:
Present a brief summary of what you found to the user before drafting. Include:
Write the email draft based on:
Show the draft to the user and ask if they'd like any changes.
Once the user approves the draft, propose it via the staging API:
curl -s -X POST <hubUrl>/app/v1/propose \
-H "Content-Type: application/json" \
-d '{"source": "gmail", "action_type": "draft_email", "action_data": {"to": "<recipient>", "subject": "<subject>", "body": "<body>"}, "purpose": "<why this draft is being created>"}'
If the email is a reply to an existing thread, include "in_reply_to": "<threadId>" in action_data.
Tell the user the draft has been proposed and is waiting for their approval in the PersonalDataHub GUI at <hubUrl>.
propose endpoint stages the draft — it does NOT send. The owner must approve it in the PersonalDataHub GUI.purpose string that gets logged in the audit trail.source_item_id to identify duplicates and merge the context.