--- name: pi-memo-inbox description: Automatically route Kai's Telegram text, short voice transcription, images, and uploaded documents into Google Calendar, today's Obsidian Todo, or Memo without requiring slash commands or repeated confirmation. Use for any incoming work update, fact, idea, action item, appointment, meeting time, trip, deadline, reminder, or content sent for capture. allowed-tools: read image_view document_parse document_ocr vault_search journal_append calendar_list calendar_create calendar_update calendar_delete --- # Pi Memo Inbox ## Default Behavior Treat every ordinary incoming text or voice message as an item to classify and persist unless Kai clearly asks only a question, requests a preview/transcription, or says not to record it. Do not wait for `/memo`, `/todo`, `/calendar`, “记一下”, “待办事项”, or “日历事项”. Classify into exactly one route and execute it immediately: 1. `calendar` - A future scheduled event, reminder, or action whose scheduling intent is clear. Missing fields may be resolved from context, memory, calendar state, and the defaults below. - Includes meetings, appointments, calls, trips, visits, reminders, and tasks explicitly scheduled for a time. 2. `todo` - A clear action that Kai or another identified person needs to perform, without an unambiguous start time. - A due date alone does not make it a calendar event; retain it as a Todo with its supplied due date. 3. `memo` - Everything else worth retaining: completed work, past events, communication results, facts, ideas, observations, hypotheses, or general notes. Do not treat every mention of a date/time as Calendar. Past events, historical statements, quoted document dates, availability discussions, and speculative times remain Memo unless they describe an actual future event/action to schedule. ## Decision Policy - Prefer the best reversible action over clarification. Execute first, report the result and any material assumptions, and let Kai correct it in the next message. - Write a Memo or Todo as soon as its factual or actionable core is understandable. Missing background, owner, priority, project linkage, or polished wording is not a reason to ask. - For incomplete Calendar requests, resolve omissions in this order: explicit values in the message; the current and recent conversation; available retained memory; a quick `vault_search`; related calendar events and free time; deterministic defaults in Calendar Workflow. - Do not ask merely because a date, start time, end time, location, or polished title was omitted. A low-risk create or uniquely identified update is reversible and should normally be executed. - Ask only when no reasonable action can be formed, when update/delete has multiple equally plausible targets, or when a wrong choice would be materially harmful and hard to reverse. - When asking is necessary, ask one concise question for the single most important missing fact. - Never ask Kai to confirm a classification that is already clear. - Do not override explicit facts or invent facts that change the nature of the item. Preserve uncertain names as heard/read and add `名称待确认` when useful instead of blocking a reversible write. Natural-language prefixes such as “记一下”, “待办”, and “放到日历” are optional hints, not required syntax. ## Journal Workflow Use `journal_append` only when the entry is ready. - factual `memo`: one concise Markdown bullet for `## 记录`. - idea-like `memo`: one concise Markdown bullet for `## 收获/想法`. - `todo`: one unchecked task for `## 今日任务`. Examples: ```text - 10:30 与 [[白帆生物]] 团队确认下一批样品安排,具体交付时间尚未确定。 - [ ] 向项目负责人确认下一批样品排期 - 可以尝试把每周项目复盘改成按风险和下一步组织。 ``` Rules: - Preserve uncertainty. - Do not invent a timestamp; add one only when known from the message or useful current capture time. - Do not add a due date unless Kai supplied it. - `journal_append` automatically writes, commits, and pushes. Report its exact result. - Never end silently after `journal_append`. Always report the target journal path, sync status, and final normalized entry. Report partial success or failure explicitly. ## Optional Context Completion When a name is probably misspelled and a correction would materially improve the entry: 1. Extract one or two discriminating search terms. 2. Call `vault_search`. 3. Read only the most relevant files if necessary. 4. Use a high-confidence correction; otherwise preserve the original and optionally mark it uncertain. 5. Continue to the appropriate write without asking for confirmation unless the uncertainty would cause a materially wrong action. Search is optional and is never a routine precondition for writing. Stop after a quick scan. ## Calendar Workflow Use calendar `gltankai@gmail.com`. Supported operations: - Query upcoming or historical events with `calendar_list`. - Create a new event with `calendar_create`. - Change the title, time, location, or description with `calendar_update`. - Delete an event with `calendar_delete`. Required: - summary; - date; - start time. Defaults: - timezone: Asia/Shanghai / `+08:00`; - missing date after context/memory lookup: next business day; - vague day parts: morning `09:00`, noon `12:00`, afternoon `14:00`, evening `19:00`; - missing time for a reminder: `09:00`; - missing time for a meeting or call: query that date and select the first sensible free hour in `09:00-12:00` or `14:00-18:00`; - end: one hour after start if absent, unless the item type clearly implies a shorter reminder or a duration is available from context; - location and description: optional. Use RFC3339 timestamps such as `2026-08-03T10:00:00+08:00`. Resolve omitted values internally and call `calendar_create` without requesting confirmation. If a date, time, person, or location was inferred rather than stated, put a short `Memo 推定:...` note in the description and include the same assumption in the receipt. Do not describe an inferred value as user-confirmed. If Kai corrects the result, list the recent event, update it immediately, and report the corrected state. Keep an explicitly supplied time even if it conflicts with another event and report the conflict. When the time itself is inferred, prefer a free slot. Use an all-day event only when the user's wording clearly denotes an all-day item and the tool supports it; otherwise use the defaults above. For natural-language queries such as “明天有什么安排”, call `calendar_list` with a bounded Shanghai-time range and answer from the returned events. For updates and deletions: 1. Call `calendar_list` first, using the narrowest reasonable date range and an optional title query. 2. Proceed directly when exactly one event matches the user's request. 3. Pass the returned event ID and exact current title to `calendar_update` or `calendar_delete`. 4. If multiple plausible events remain, ask one concise disambiguation question. Never guess an event ID. 5. Treat an explicit “删除/取消/移除日历事项” request as authorization to delete the unique match; do not ask for a second confirmation. 6. Never update or delete an event merely because it was mentioned. The user must clearly request the change. Never end silently after a calendar tool call. Report whether the event was listed, created, updated, or deleted, including its title and time when available. ## Voice Telegram short voice is transcribed upstream by the active message gateway using Qwen3-ASR. Before routing it, lightly normalize spoken language: - Remove meaningless fillers, stutters, duplicated fragments, and abandoned self-corrections. - Reorder only enough to make the sentence readable. - Preserve intent, tone, negation, conditions, names, organizations, numbers, dates, and times. - Do not summarize away actionable details or add facts absent from the transcript. Use the normalized text for journal or calendar writes. Resolve omitted Calendar fields with conversation, memory, calendar context, and the default policy; report the assumptions instead of asking first. For an uncertain proper noun in Memo or Todo, preserve it and optionally mark `名称待确认`; do not block writing. Do not invoke meeting-recording workflows. ## Images When the message gateway says that an image was uploaded to `.ccgram-uploads/...`: 1. Call `image_view` with exactly that path. 2. Understand both visible content and text in the image using the active multimodal model. 3. Combine the image with any caption or adjacent user instruction, then apply the same `calendar`, `todo`, or `memo` classification. 4. If the user's intent is only “看看/这是什么”, describe the image and do not write anything. 5. When the image contains a schedulable event or action and the user sent it for capture, route it directly. Resolve unreadable or omitted fields from the caption, conversation, memory, calendar context, and defaults; report any material inference. 6. Never read an image outside the Memo workspace `.ccgram-uploads` directory. Do not invoke meeting-recording workflows. ## Documents and OCR When the message gateway reports a PDF, Word, PowerPoint, Excel, HTML, text file, or image: 1. Call `document_parse` with exactly the `.ccgram-uploads/...` path. It uses AnyDoc for office documents and pdf-inspector for PDF extraction and OCR routing. 2. If `document_parse` reports `OCR required`, call `document_ocr` with the same source path and its reported page numbers. For an image, a short scan without page routing, or a visibly incomplete complex layout, call `document_ocr` without `pages`. Do not treat partial embedded text as the whole document. 3. Treat parsed or OCR text as derivative, with the uploaded filename as its source. Do not claim perfect transcription. 4. For calendar intent, extract the event title, date, start time, end time, location/address, organizer, and useful contact details. 5. Reconcile date and time against the caption, recent conversation, memory, vault, and calendar. Use the default policy when a best value remains unstated, and identify that value as inferred in the receipt. 6. When the document and caption describe an event to schedule, create it directly; no command or confirmation is required unless no reasonable action exists or the error would be hard to reverse. 7. Put concise provenance such as `来源:文档解析()` in the event description. 8. Do not persist parsed document text to the vault unless the user separately asks to record it.