Add connected email accounts and draft-only agent tools - #897
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 45add7afb8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| import Agent.CLI.Mail.OAuth | ||
| import Agent.CLI.Mail.Store (MailProvider(GmailProvider)) | ||
| import Control.Concurrent (threadDelay) | ||
| import Control.Exception (bracket, finally) |
There was a problem hiding this comment.
Use the repository's safe exception API
This new test imports Control.Exception, although the repository requires Haskell code to prefer Control.Exception.Safe; import bracket and finally from the safe-exceptions module to keep exception handling consistent with the rest of the project.
AGENTS.md reference: AGENTS.md:L204-L205
Useful? React with 👍 / 👎.
| providerJson token (graphBase <> "/mailFolders") | ||
| [("$top", Just (BS8.pack (show maximum))), | ||
| ("$select", Just "id,displayName,unreadItemCount")] |
There was a problem hiding this comment.
Traverse child folders when listing Outlook mailboxes
For Microsoft accounts with nested folders, Graph's /me/mailFolders endpoint returns only folders directly under the mailbox root. Because the tool requires mailbox IDs to come from this listing, child folders can never be selected or searched; recursively request each folder's childFolders collection, bounded by the configured maximum.
Useful? React with 👍 / 👎.
| let fetchLimit | ||
| | isJust request.mailSearchHasAttachments = 50 | ||
| | otherwise = boundedCount 50 request.mailSearchLimit | ||
| uids = take fetchLimit | ||
| (reverse (concatMap searchUids searched)) |
There was a problem hiding this comment.
Continue scanning IMAP results for attachment matches
When has_attachments is supplied, only the newest 50 UIDs are fetched before the attachment predicate is applied. If those 50 messages fail the predicate but older search hits satisfy it, email_search silently returns too few—or zero—results despite the requested limit; scan additional bounded batches until enough matching summaries are collected or the search results are exhausted.
Useful? React with 👍 / 👎.
| hasAttachment = "\"attachment\"" `Text.isInfixOf` joined | ||
| || " attachment " `Text.isInfixOf` joined |
There was a problem hiding this comment.
Detect filename-only IMAP attachments
For MIME parts whose BODYSTRUCTURE has a filename or name parameter but an INLINE or absent disposition, this substring check reports has_attachments = false, even though the MIME decoder later treats any filename-bearing part as an attachment. This makes summaries inconsistent with email_get and incorrectly removes such messages from has_attachments=true searches; parse the filename/name fields from BODYSTRUCTURE as attachment indicators too.
Useful? React with 👍 / 👎.
45add7a to
7fc9ee3
Compare
7fc9ee3 to
981a1ae
Compare
…-runtime # Conflicts: # packages/agent-cli/ffi/Agent/CLI/MacOS/Bridge.hs
Summary
email_create_draft,email_update_draft, andemail_reply_draft; all save provider-side drafts and returnsent: falsereply_tovalue so reply-draft approval shows the exact recipientSafety and permissions
AlwaysConfirm: yolo, project/session grants, and remembered tool approvals cannot bypass a fresh user confirmation; plan mode and child agents cannot perform the writeEXPUNGEexistsgmail.readonly+gmail.compose(Google defines compose broadly enough to permit send, but the runtime exposes no send path); Microsoft requestsMail.ReadWriteand neverMail.Send\Draftsmailbox, synchronizing literals, and UIDPLUS; updates use exact UID/flag checks andUID EXPUNGEonlyVerification
agent-tuisuite: 215 examples, 0 failuresagent-clirun: 1,617 passed and 1 pending; the 23 tests initially blocked by macOS PostgreSQL socket-path length all passed in a 27/27 short-TMPDIR rerunnix build .#agent-native-bridgegit diff --checkand no-send/SMTP surface auditThe dependent macOS PR pins public commit
5ea817d5428f4c6d8a243ee34cd87c7b15f804c0.