Improved mailboxes to include sent mails and drafts (#1038)

This commit is contained in:
Thorsten Sommer authored and GitHub committed 2026-10-10 10:48:54 +02:00
1 parent 67d44588d4
commit 5c319c45a0
31 files changed
+792 -103

No files matched your search

+5 -1
View File
@@ -198,11 +198,15 @@ The data sources are checked again before each search, since rounds may have pas
- `read_mail` reads one mail in pages of 30,000 characters, an attachment by its number, and the header block on request. It names the mail this one replies to, when that one is in the index.
- `count_mails` counts with the same conditions, by folder or by sender on request, and adds how many mails the folders hold on the server.
The index holds the sent mails and the drafts as well. Without a root folder, they belong to the whole mailbox anyway; with one, `DataSourceMailbox.IncludeSentAndDrafts` adds them from outside it, see `MailFolderSelection`. Drafts are indexed whatever their age, like flagged mails. `search_mails` and `count_mails` take `special_folder` with `sent` or `drafts`, which `MailConditions` resolves by what the server marks a folder as (`MailFolderRecord.SpecialUse`), never by its name, since that differs by server and language. Results mark such mails with `special_folder` as well, so the model can tell what the user wrote from what the user received.
Asking for drafts starts a sync of the mailbox when its last complete sync is older than a minute, see `MailDraftSync`: a user who saved a draft a moment ago and asks the AI to improve it expects the AI to find it, while the next sync at the interval may be a quarter of an hour away. `DataSourceEmbeddingService.RequestMailboxSyncAsync` queues it as `DataSourceEmbeddingRefreshMode.TOOL_REQUEST`, which keeps to the automatic refresh setting and never signs in despite a refused sign-in. The result says that drafts may be missing or outdated until the sync is done. The model cannot save a draft; it proposes the improved text in its answer.
The tools offer the mailboxes which `MailboxRetrievalService.GetReadableMailboxes` returns. The chat provider and the embedding provider both have to meet the level of a mailbox, because the embedding provider receives the query, which the model may have written from a mail. A mailbox requires a level from `VERY_LOW` to `HIGH`; `NONE`, `UNTRUSTED`, and `UNKNOWN` would let almost every provider through, so they close the mailbox instead. A mailbox on a server the organization does not allow is left out as well, see `MailServerPolicy`. Each call checks again, since rounds may have passed since the tools were offered, and `read_mail` finds a mail only in the mailboxes the provider may read.
Mails are written by others. Everything of a mail which reaches the model, from the subject and the addresses to the passages and the names of attachments, goes through one `PromptInjectionGuardService` batch per call, as `PromptInjectionSource.MailContent`. Only the mailboxes whose content reached the model raise the requirements of the chat; of several, the strictest restriction wins, and the first mailbox demanding it is named. An organization's `DataMailboxes.MinimumOutboundDataRestriction` tightens a mailbox whose own level is less strict. Found and read mails become sources under `mailbox://<mailbox ID>/<mail ID>`, which the sources list shows as text without a link, see `SourceExtensions.IsMailSource`. AI Studio cannot read an encrypted mail, only its header, and the instructions tell the model to say so rather than guess.
Logs name a mailbox and its ID, never a subject, a sender or recipient, a folder, or an attachment. `ToolExecutor` logs the message of every exception, so a mail tool must not throw with such a value either. A `folder` the mailboxes do not know is therefore answered in the result, together with the folders to choose from, rather than refused by an exception.
Logs name a mailbox and its ID, never a subject, a sender or recipient, a folder, or an attachment. `ToolExecutor` logs the message of every exception, so a mail tool must not throw with such a value either. A `folder` or a `special_folder` the mailboxes do not know is therefore answered in the result, together with the folders to choose from, rather than refused by an exception.
## Checklist