Skip to content

extend to email address list#1363

Merged
iceljc merged 1 commit into
SciSharp:masterfrom
iceljc:master
Jun 11, 2026
Merged

extend to email address list#1363
iceljc merged 1 commit into
SciSharp:masterfrom
iceljc:master

Conversation

@iceljc

@iceljc iceljc commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

PR Summary by Qodo

Support sending email to multiple recipients
✨ Enhancement ⚙️ Configuration changes 🕐 10-20 Minutes

Grey Divider

Walkthroughs

Description
• Extend email sender function to accept multiple recipient addresses.
• Update LLM input context and function schema to use to_address_list.
• Log all recipients in the success message for better traceability.
Diagram
graph TD
  A["FunctionArgs JSON"] --> B["LlmContextIn (to_address_list)"] --> C["HandleEmailSenderFn"] --> D["MimeMessage (To: many)"] --> E{{"SMTP server"}}
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Backward-compatible input (accept both keys)
  • ➕ Avoids breaking existing agents/tools still sending to_address
  • ➕ Allows gradual migration while keeping to_address_list as canonical
  • ➖ Slightly more parsing/validation logic
  • ➖ Requires clear deprecation plan and cutoff
2. Polymorphic `to_address` (string or array)
  • ➕ Most flexible for callers
  • ➕ Single parameter name reduces schema churn
  • ➖ Weaker schema guarantees (harder validation/documentation)
  • ➖ More complex deserialization (JsonElement/custom converter)

Recommendation: Keeping an explicit to_address_list is a good, strongly-typed contract. Consider short-term backward compatibility by also accepting the legacy to_address field (and mapping it into the list) to prevent breaking existing function callers; then deprecate and remove after clients migrate.

Grey Divider

File Changes

Enhancement (2)
HandleEmailSenderFn.cs Iterate recipient list when building MimeMessage +8/-3

Iterate recipient list when building MimeMessage

• Replaces single-recipient handling with a filtered recipient list and adds each address to 'mailMessage.To'. Updates logging to include the full recipient list.

src/Plugins/BotSharp.Plugin.EmailHandler/Functions/HandleEmailSenderFn.cs


LlmContextIn.cs Rename 'to_address' to 'to_address_list' in LLM context model +2/-2

Rename 'to_address' to 'to_address_list' in LLM context model

• Updates the input model to deserialize a list of recipient emails ('IEnumerable<string>') under 'to_address_list' instead of a single address.

src/Plugins/BotSharp.Plugin.EmailHandler/LlmContexts/LlmContextIn.cs


Other (1)
util-email-handle_email_sender.json Update function schema to require 'to_address_list' array +7/-4

Update function schema to require 'to_address_list' array

• Changes the function parameter definition from a single string recipient to an array of strings and updates the required fields accordingly.

src/Plugins/BotSharp.Plugin.EmailHandler/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/functions/util-email-handle_email_sender.json


Grey Divider

Qodo Logo

@iceljc iceljc merged commit 4bf7634 into SciSharp:master Jun 11, 2026
0 of 3 checks passed
@qodo-code-review

qodo-code-review Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (2)

Grey Divider


Action required

1. Recipients not validated empty 📘 Rule violation ☼ Reliability
Description
HandleEmailSenderFn.Execute defaults recipients to an empty collection when args/ToAddresses
is null and then proceeds without validating that at least one recipient exists, so invalid boundary
inputs aren’t rejected early. This can mask client/LLM input errors (e.g., missing or mis-shaped
to_address_list) and lead to unpredictable downstream behavior or a late SMTP send failure instead
of a clear validation error.
Code

src/Plugins/BotSharp.Plugin.EmailHandler/Functions/HandleEmailSenderFn.cs[R32-35]

+        var recipients = args?.ToAddresses?.Where(x => !string.IsNullOrWhiteSpace(x)) ?? [];
        var body = args?.Content;
        var subject = args?.Subject;
        var isNeedAttachments = args?.IsNeedAttachemnts ?? false;
Evidence
PR Compliance ID 3 requires explicit null/empty validation at system boundaries and failing fast
rather than silently applying defaults; however, the code sets recipients to [] when inputs are
missing and only adds To addresses inside a foreach, with no guard like if (!recipients.Any())
before building/sending the email via SMTP. As a result, when to_address_list is omitted or
malformed, the function still calls the SMTP send path with an empty recipients list, turning an
input/client error into a runtime send failure; this contrasts with other utility callbacks in the
repo that validate required arguments early and return a user-facing error without invoking the
external side effect.

src/Plugins/BotSharp.Plugin.EmailHandler/Functions/HandleEmailSenderFn.cs[32-46]
src/Plugins/BotSharp.Plugin.EmailHandler/Functions/HandleEmailSenderFn.cs[29-63]
src/Plugins/BotSharp.Plugin.Twilio/OutboundPhoneCallHandler/Functions/OutboundPhoneCallFn.cs[41-57]
Best Practice: Learned patterns

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`HandleEmailSenderFn.Execute` currently accepts missing/empty boundary inputs by defaulting `recipients` to an empty collection and continuing execution, which can result in attempting to send an email with no recipients and failing late (SMTP/Mime creation) with a generic failure. Update the handler to validate required inputs at the boundary (at minimum: recipients; optionally: subject and body) and fail fast with a clear, predictable validation error/result returned to the caller, per compliance requirements.

## Issue Context
- `recipients` is computed with a null-coalescing default (e.g., `args?.ToAddresses ?? []`), so null/missing `to_address_list` is silently treated as “no recipients”.
- The PR changed input from `to_address` to `to_address_list`; the implementation filters null/whitespace and adds recipients in a loop, but never checks that any were actually added before calling the SMTP send.
- When the LLM omits or mis-shapes `to_address_list`, this becomes a runtime send attempt failure rather than a clear validation error.

## Fix Focus Areas
- src/Plugins/BotSharp.Plugin.EmailHandler/Functions/HandleEmailSenderFn.cs[31-62]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. PII in interpolated log 📘 Rule violation ⛨ Security
Description
The success log uses string interpolation and includes recipient email addresses and subject, which
can leak sensitive/PII into operational logs and is not structured for queryable context. It also
logs a success path at Warning level, which is not an appropriate severity.
Code

src/Plugins/BotSharp.Plugin.EmailHandler/Functions/HandleEmailSenderFn.cs[61]

+            _logger.LogWarning($"Email successfully send over to {string.Join(",", recipients)}. Email Subject: {subject} [{response}]");
Evidence
PR Compliance ID 4 requires safe/actionable logging: avoid sensitive outputs, use structured
templates (not string interpolation), and appropriate log levels. The added line logs recipient
email addresses and subject using $"...{...}" and uses LogWarning on a success path.

src/Plugins/BotSharp.Plugin.EmailHandler/Functions/HandleEmailSenderFn.cs[61-61]
Best Practice: Learned patterns

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A success log message is written via string interpolation and includes recipient email addresses and the email subject. This can expose PII/sensitive data and is not structured logging; additionally, `LogWarning` is used for a successful operation.

## Issue Context
The code logs `string.Join(",", recipients)` and `subject` in a warning-level message.

## Fix Focus Areas
- src/Plugins/BotSharp.Plugin.EmailHandler/Functions/HandleEmailSenderFn.cs[61-61]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Untrimmed recipient addresses 🐞 Bug ≡ Correctness
Description
Recipient strings are not trimmed before being passed to MailboxAddress, so leading/trailing spaces
in to_address_list can cause invalid recipient values and failed sends. The function schema also
states recipients should be unique, but the implementation currently allows duplicates.
Code

src/Plugins/BotSharp.Plugin.EmailHandler/Functions/HandleEmailSenderFn.cs[R43-46]

+            foreach (var recipient in recipients)
+            {
+                mailMessage.To.Add(new MailboxAddress("", recipient));
+            }
Evidence
HandleEmailSenderFn filters out whitespace-only values but does not trim or deduplicate; it directly
uses each recipient string to construct MailboxAddress. The function schema explicitly calls for
unique emails, indicating duplicates are not desired.

src/Plugins/BotSharp.Plugin.EmailHandler/Functions/HandleEmailSenderFn.cs[31-47]
src/Plugins/BotSharp.Plugin.EmailHandler/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/functions/util-email-handle_email_sender.json[7-13]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Recipient emails are only filtered for whitespace-only values, but they are not trimmed or de-duplicated before being used to create `MailboxAddress` entries.

## Issue Context
The function schema describes each item in `to_address_list` as "valid and unique". Current code uses the raw string values when adding to `mailMessage.To`.

## Fix Focus Areas
- src/Plugins/BotSharp.Plugin.EmailHandler/Functions/HandleEmailSenderFn.cs[31-47]
- src/Plugins/BotSharp.Plugin.EmailHandler/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/functions/util-email-handle_email_sender.json[7-13]

Suggested approach:
- Normalize recipients when building the list:
 - `Select(x => x.Trim())`
 - `Where(x => !string.IsNullOrWhiteSpace(x))`
 - `Distinct(StringComparer.OrdinalIgnoreCase)` (to align with "unique")
- Use the normalized list for both `mailMessage.To.Add(...)` and logging.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment on lines +32 to 35
var recipients = args?.ToAddresses?.Where(x => !string.IsNullOrWhiteSpace(x)) ?? [];
var body = args?.Content;
var subject = args?.Subject;
var isNeedAttachments = args?.IsNeedAttachemnts ?? false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Recipients not validated empty 📘 Rule violation ☼ Reliability

HandleEmailSenderFn.Execute defaults recipients to an empty collection when args/ToAddresses
is null and then proceeds without validating that at least one recipient exists, so invalid boundary
inputs aren’t rejected early. This can mask client/LLM input errors (e.g., missing or mis-shaped
to_address_list) and lead to unpredictable downstream behavior or a late SMTP send failure instead
of a clear validation error.
Agent Prompt
## Issue description
`HandleEmailSenderFn.Execute` currently accepts missing/empty boundary inputs by defaulting `recipients` to an empty collection and continuing execution, which can result in attempting to send an email with no recipients and failing late (SMTP/Mime creation) with a generic failure. Update the handler to validate required inputs at the boundary (at minimum: recipients; optionally: subject and body) and fail fast with a clear, predictable validation error/result returned to the caller, per compliance requirements.

## Issue Context
- `recipients` is computed with a null-coalescing default (e.g., `args?.ToAddresses ?? []`), so null/missing `to_address_list` is silently treated as “no recipients”.
- The PR changed input from `to_address` to `to_address_list`; the implementation filters null/whitespace and adds recipients in a loop, but never checks that any were actually added before calling the SMTP send.
- When the LLM omits or mis-shapes `to_address_list`, this becomes a runtime send attempt failure rather than a clear validation error.

## Fix Focus Areas
- src/Plugins/BotSharp.Plugin.EmailHandler/Functions/HandleEmailSenderFn.cs[31-62]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

message.Content = response;

_logger.LogWarning($"Email successfully send over to {recipient}. Email Subject: {subject} [{response}]");
_logger.LogWarning($"Email successfully send over to {string.Join(",", recipients)}. Email Subject: {subject} [{response}]");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Pii in interpolated log 📘 Rule violation ⛨ Security

The success log uses string interpolation and includes recipient email addresses and subject, which
can leak sensitive/PII into operational logs and is not structured for queryable context. It also
logs a success path at Warning level, which is not an appropriate severity.
Agent Prompt
## Issue description
A success log message is written via string interpolation and includes recipient email addresses and the email subject. This can expose PII/sensitive data and is not structured logging; additionally, `LogWarning` is used for a successful operation.

## Issue Context
The code logs `string.Join(",", recipients)` and `subject` in a warning-level message.

## Fix Focus Areas
- src/Plugins/BotSharp.Plugin.EmailHandler/Functions/HandleEmailSenderFn.cs[61-61]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant