Skip to content
Corven Email SDK
Esc
↑↓navigate↵open⌘Jpreview
On this page

Approve agent-requested email

Let a model propose content while the host owns sender, account, keys, policy and approval.

Use EmailAgent from @corven/email-sdk/agent to expose a constrained proposal boundary. Model input contains to, subject and body. The host supplies the sender and the configured Email service.

import { Effect, Layer } from "effect";
import type { Redacted } from "effect";
import { EmailAgent, EmailAgentApproval, emailAgentLayer } from "@corven/email-sdk/agent";
import type { IEmailAgentApproval } from "@corven/email-sdk/agent";
import { postmarkEmailLayer } from "@corven/email-sdk/postmark";

export const hostApprovedAgentLayer = (
  serverToken: Redacted.Redacted,
  review: IEmailAgentApproval["review"],
) =>
  emailAgentLayer({ from: { address: "host@fictional.invalid", name: "Fictional host" } }).pipe(
    Layer.provide(Layer.succeed(EmailAgentApproval, EmailAgentApproval.of({ review }))),
    Layer.provide(postmarkEmailLayer({ serverToken })),
  );

export const fictionalAgentSubmission = Effect.gen(function* submitHostReviewedNotification() {
  const agent = yield* EmailAgent;

  return yield* agent.submit({
    body: { text: "Fictional content for the host to review." },
    subject: "Fictional agent notification",
    to: "recipient@fictional.invalid",
  });
});

The account Layer still needs HTTP transport. The sample accepts a host review callback rather than automatically approving proposals.

Review effective candidates

EmailAgentApproval.review receives owned message, options and all effective previews. Defaults, transformations and routes have already been prepared, so review the actual candidates rather than the model’s earlier draft.

Return Approved only when host policy permits that exact operation. Declined fails with EmailAgentApprovalError; unavailable review must remain an explicit failure. The SDK validates and dispatches the same prepared operation after approval.

Keep authority in the host

Do not accept model-supplied sender accounts, credentials, route policy or replay keys as authority. Framework approval flags, confirmation text and tool-call IDs do not replace EmailAgentApproval.

Approval does not prove account permission, submission or delivery. A failed or interrupted tool call can leave the outcome unknown, so do not retry automatically. Use AI tools for a framework bridge and prepared operations for scope and callback semantics.