Skip to content
This repository was archived by the owner on Jan 23, 2026. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# @agentuity/sdk Changelog

## 0.0.157

### Patch Changes

- Removed send from email (unavailable at the moment)

## [0.0.156] - 2025-10-15

### Added
Expand Down
5 changes: 3 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@agentuity/sdk",
"version": "0.0.156",
"version": "0.0.157",
"description": "The Agentuity SDK for NodeJS and Bun",
"license": "Apache-2.0",
"public": true,
Expand Down
52 changes: 0 additions & 52 deletions src/apis/email.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,58 +4,6 @@ import type { EmailService } from '../types';
import { POST } from './api';

export default class EmailApi implements EmailService {
/**
* send an email
*/
async send(
agentId: string,
email: string,
authToken: string,
messageId: string
): Promise<void> {
const tracer = getTracer();
const currentContext = context.active();

// Create a child span using the current context
const span = tracer.startSpan('agentuity.email.send', {}, currentContext);

try {
// Create a new context with the child span
const spanContext = trace.setSpan(currentContext, span);

// Execute the operation within the new context
return await context.with(spanContext, async () => {
span.setAttribute('@agentuity/agentId', agentId);
span.setAttribute('@agentuity/emailMessageId', messageId);

const resp = await POST(
'/email/send',
email,
{
'Content-Type': 'message/rfc822',
'X-Agentuity-Message-Id': messageId,
},
undefined,
authToken
);
if (resp.status === 200) {
span.setStatus({ code: SpanStatusCode.OK });
return;
}
const body = await resp.response.text();
span.setStatus({ code: SpanStatusCode.ERROR, message: body });
throw new Error(
`error sending email: ${resp.response.statusText} (${resp.response.status})${body}`
);
});
} catch (ex) {
recordException(span, ex);
throw ex;
} finally {
span.end();
}
}

/**
* send an email reply to an incoming email
*/
Expand Down
91 changes: 0 additions & 91 deletions src/io/email.ts
Original file line number Diff line number Diff line change
Expand Up @@ -459,97 +459,6 @@ export class Email {
return '';
}

/**
* Send a new email to the specified recipients.
*
* @param req - The agent request containing metadata with email-auth-token
* @param context - The agent context
* @param to - Array of recipient email addresses
* @param email - The email content (subject, text, html, attachments)
* @param from - Optional sender information (defaults to the recipient of the incoming email)
* @returns Promise resolving to the message ID of the sent email
* @throws Error if email-auth-token is missing, recipients list is empty, or from address is invalid
*/
async send(
req: AgentRequest,
context: AgentContext,
to: string[],
email: EmailReply,
from?: {
name?: string;
email?: string;
}
): Promise<string> {
const authToken = req.metadata?.['email-auth-token'] as string;
if (!authToken) {
throw new Error(
'email authorization token is required but not found in metadata'
);
}

return (async () => {
let attachments: Attachment[] = [];
if (email.attachments) {
attachments = await Promise.all(
email.attachments.map(async (attachment) => {
const resp = await fromDataType(attachment.data);
return {
filename: attachment.filename,
content: await resp.data.buffer(),
contentType: resp.data.contentType,
contentDisposition:
attachment.contentDisposition ?? ('attachment' as const),
};
})
);
}

const normalizedTo = to.map((addr) => addr.trim()).filter(Boolean);
if (normalizedTo.length === 0) {
throw new Error('at least one recipient email is required');
}

const fromAddress = from?.email ?? this.toEmail();
if (!fromAddress) {
throw new Error('a valid from email address is required');
}

const mail = new MailComposer({
date: new Date(),
from: {
name: from?.name ?? context.agent.name,
address: fromAddress,
},
to: normalizedTo.join(', '),
subject: email.subject ?? '',
text: email.text,
html: email.html,
attachments,
});
const newemail = mail.compile();

return new Promise<string>((resolve, reject) => {
newemail.build(async (err, message) => {
if (err) {
reject(err);
} else {
try {
await context.email.send(
context.agent.id,
message.toString(),
authToken,
newemail.messageId()
);
resolve(newemail.messageId());
} catch (ex) {
reject(ex);
}
}
});
});
})();
}

/**
* send a reply to the email
*/
Expand Down
10 changes: 0 additions & 10 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -669,16 +669,6 @@ export interface VectorStorage {
* EmailService provides a way to send email replies to incoming emails
*/
export interface EmailService {
/**
* Send a new email to the specified recipients.
*/
send(
agentId: string,
email: string,
authToken: string,
messageId: string
): Promise<void>;

/**
* send an email reply to an incoming email
*
Expand Down
4 changes: 2 additions & 2 deletions test/io/email.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Test attachment content

const email = await parseEmail(Buffer.from(emailContent));

expect(email.attachments).toBeDefined();
expect(() => email.attachments()).not.toThrow();
const attachments = email.attachments();
expect(attachments).toHaveLength(0);
});
Expand All @@ -82,7 +82,7 @@ Test attachment content

const email = await parseEmail(Buffer.from(emailContent));

expect(email.attachments).toBeDefined();
expect(() => email.attachments()).not.toThrow();
const attachments = email.attachments();
expect(attachments).toHaveLength(0);
});
Expand Down
Loading