Fixed mail search leaving out mails that did not fit into a search (#1169)

This commit is contained in:
Thorsten Sommer authored and GitHub committed 2026-11-06 07:48:40 +01:00
1 parent 188d17688a
commit 7f0d0ed8f6
11 files changed
+924 -245

No files matched your search

+2 -2
View File
@@ -243,7 +243,7 @@ Both ways of searching ask one place what their passages demand, `DataSourceRequ
`search_mails`, `read_mail`, and `count_mails` form the collection `mailboxes`, behind the preview `PRE_MAILBOXES_2026` on top of `PRE_RAG_2024`. None of them asks a mail server anything. They read the local index which `MailboxIndexer` keeps, through `MailboxRetrievalService`. Mailboxes are kept in a list of their own, `Data.Mailboxes`, so `semantic_search` and the classic RAG process never see one.
- `search_mails` searches with a `query` by meaning and by words, and returns each mail once with the passage which matched best. Without a query, it lists the mails meeting the conditions, the most recently received first. Results come in pages per mailbox, so a page after the first needs exactly one mailbox. All mailboxes share a budget of 100,000 characters and take turns in it.
- `search_mails` searches with a `query` by meaning and by words, and returns each mail once with the passage which matched best. Without a query, it lists the mails meeting the conditions, the most recently received first. A page of the search holds mails up to 100,000 characters, measured after the filter, as with `semantic_search`: a mailbox returns its mails in pages of its own, as many as it is set to return, and each of them is cut into one or more pages of the search, see `SearchMailsTool.SearchAsync`. No mail is skipped, and `has_more` is exact. A page after the first needs exactly one mailbox. Several mailboxes share the first page and take turns in it; a mailbox stops at its first mail which no longer fits, and the result points to a search of that mailbox alone, from page 1. A result shows only a part of a mail, each text and each list with a limit, see `PendingMail`, so a single mail stays far below a page; `read_mail` shows the whole mail.
- `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.
@@ -253,7 +253,7 @@ Asking for drafts starts a sync of the mailbox when its last complete sync is ol
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.
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 `PromptInjectionGuardService` as `PromptInjectionSource.MailContent`, and the user hears once per call what was filtered: `read_mail` and `count_mails` filter in one batch, `search_mails` in one batch per page of a mailbox it reads, within one `BeginAction`. 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` 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.