@dbx-tools/email 0.6.218 → 0.6.219
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -0
- package/index.ts +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +2 -2
- package/lib/src/tool.d.ts +13 -5
- package/lib/src/tool.js +9 -9
- package/package.json +7 -7
- package/src/tool.ts +15 -9
package/README.md
CHANGED
|
@@ -65,6 +65,26 @@ the first approved send; outbox mode skips the check and logs loudly instead.
|
|
|
65
65
|
requires Mastra storage, so register `lakebase()` or configure storage explicitly
|
|
66
66
|
in the Mastra plugin.
|
|
67
67
|
|
|
68
|
+
`emailTool({ requireApproval })` also accepts Mastra's native conditional
|
|
69
|
+
approval function. Use it with a Mastra `Classifier` or a durable, user-scoped
|
|
70
|
+
fingerprint policy when previously reviewed calls should reduce future prompts:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
const sendEmail = emailTool({
|
|
74
|
+
requireApproval: async (input, { requestContext } = {}) =>
|
|
75
|
+
approvalPolicy.requiresReview({
|
|
76
|
+
input,
|
|
77
|
+
userId: requestContext?.["mastra__resourceId"],
|
|
78
|
+
}),
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
The callback returns `true` when human review is still required and `false`
|
|
83
|
+
when Mastra may execute. Fail closed in the policy. Regular Mastra agents do not
|
|
84
|
+
provide a built-in durable "remember this approval" store; Agent Controller
|
|
85
|
+
permission rules are a separate runtime, so this package does not emulate them
|
|
86
|
+
client-side.
|
|
87
|
+
|
|
68
88
|
The plugin does not decide how approval is presented. It emits a Mastra tool
|
|
69
89
|
suspension and expects the host UI to resume that tool call with an approval or
|
|
70
90
|
denial result. [`@dbx-tools/ui-email`](../../ui/email) provides the matching
|
package/index.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Hand edits are overwritten on the next watch; this file is read-only.
|
|
4
4
|
|
|
5
5
|
export const PACKAGE_IDENTIFIER = "@dbx-tools/email";
|
|
6
|
-
export const PACKAGE_VERSION = "0.6.
|
|
6
|
+
export const PACKAGE_VERSION = "0.6.219";
|
|
7
7
|
export * as brand from "./src/brand.ts";
|
|
8
8
|
export * as config from "./src/config.ts";
|
|
9
9
|
export * as defaults from "./src/defaults.ts";
|
package/lib/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const PACKAGE_IDENTIFIER = "@dbx-tools/email";
|
|
2
|
-
export declare const PACKAGE_VERSION = "0.6.
|
|
2
|
+
export declare const PACKAGE_VERSION = "0.6.219";
|
|
3
3
|
export * as brand from "./src/brand.ts";
|
|
4
4
|
export * as config from "./src/config.ts";
|
|
5
5
|
export * as defaults from "./src/defaults.ts";
|
package/lib/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Regenerated from the exporting modules in ./src.
|
|
3
3
|
// Hand edits are overwritten on the next watch; this file is read-only.
|
|
4
4
|
export const PACKAGE_IDENTIFIER = "@dbx-tools/email";
|
|
5
|
-
export const PACKAGE_VERSION = "0.6.
|
|
5
|
+
export const PACKAGE_VERSION = "0.6.219";
|
|
6
6
|
export * as brand from "./src/brand.js";
|
|
7
7
|
export * as config from "./src/config.js";
|
|
8
8
|
export * as defaults from "./src/defaults.js";
|
|
@@ -20,4 +20,4 @@ export { normalizeMarkdown } from "./src/markdown.js";
|
|
|
20
20
|
export { EmailPlugin, email } from "./src/plugin.js";
|
|
21
21
|
export { SYSTEM_SENDER_LOCAL_PART } from "./src/sender.js";
|
|
22
22
|
export { SEND_EMAIL_DESCRIPTION } from "./src/tool.js";
|
|
23
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxrQkFBa0IsQ0FBQztBQUNyRCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsU0FBUyxDQUFDO0FBQ3pDLE9BQU8sS0FBSyxLQUFLLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEMsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssUUFBUSxNQUFNLG1CQUFtQixDQUFDO0FBQzlDLE9BQU8sS0FBSyxTQUFTLE1BQU0scUJBQXFCLENBQUM7QUFDakQsT0FBTyxLQUFLLFFBQVEsTUFBTSxtQkFBbUIsQ0FBQztBQUM5QyxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssSUFBSSxNQUFNLGVBQWUsQ0FBQztBQUN0QyxPQUFPLEtBQUssU0FBUyxNQUFNLG9CQUFvQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxzQkFBc0IsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRWpHLE9BQU8sRUFBRSxlQUFlLEVBQUUsaUJBQWlCLEVBQUUsZUFBZSxFQUFFLG9CQUFvQixFQUFFLDJCQUEyQixFQUFFLG9CQUFvQixFQUFFLGNBQWMsRUFBRSxtQkFBbUIsRUFBRSxxQkFBcUIsRUFBRSxzQkFBc0IsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRXJQLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUVqRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUN0RCxPQUFPLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3JELE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNELE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGVBQWUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEdFTkVSQVRFRCBieSBwcm9qZW4gd2F0Y2ggLSBETyBOT1QgRURJVC5cbi8vIFJlZ2VuZXJhdGVkIGZyb20gdGhlIGV4cG9ydGluZyBtb2R1bGVzIGluIC4vc3JjLlxuLy8gSGFuZCBlZGl0cyBhcmUgb3ZlcndyaXR0ZW4gb24gdGhlIG5leHQgd2F0Y2g7IHRoaXMgZmlsZSBpcyByZWFkLW9ubHkuXG5cbmV4cG9ydCBjb25zdCBQQUNLQUdFX0lERU5USUZJRVIgPSBcIkBkYngtdG9vbHMvZW1haWxcIjtcbmV4cG9ydCBjb25zdCBQQUNLQUdFX1ZFUlNJT04gPSBcIjAuNi4yMTlcIjtcbmV4cG9ydCAqIGFzIGJyYW5kIGZyb20gXCIuL3NyYy9icmFuZC50c1wiO1xuZXhwb3J0ICogYXMgY29uZmlnIGZyb20gXCIuL3NyYy9jb25maWcudHNcIjtcbmV4cG9ydCAqIGFzIGRlZmF1bHRzIGZyb20gXCIuL3NyYy9kZWZhdWx0cy50c1wiO1xuZXhwb3J0ICogYXMgZW1haWxIdG1sIGZyb20gXCIuL3NyYy9lbWFpbC1odG1sLnRzXCI7XG5leHBvcnQgKiBhcyBtYXJrZG93biBmcm9tIFwiLi9zcmMvbWFya2Rvd24udHNcIjtcbmV4cG9ydCAqIGFzIG91dGJveCBmcm9tIFwiLi9zcmMvb3V0Ym94LnRzXCI7XG5leHBvcnQgKiBhcyBwbHVnaW4gZnJvbSBcIi4vc3JjL3BsdWdpbi50c1wiO1xuZXhwb3J0ICogYXMgc2VuZGVyIGZyb20gXCIuL3NyYy9zZW5kZXIudHNcIjtcbmV4cG9ydCAqIGFzIHRvb2wgZnJvbSBcIi4vc3JjL3Rvb2wudHNcIjtcbmV4cG9ydCAqIGFzIHRyYW5zcG9ydCBmcm9tIFwiLi9zcmMvdHJhbnNwb3J0LnRzXCI7XG5leHBvcnQgeyBERUZBVUxUX1NNVFBfUE9SVCwgSU1QTElDSVRfVExTX1NNVFBfUE9SVCwgRU1BSUxfQ09ORklHX1NDSEVNQSB9IGZyb20gXCIuL3NyYy9jb25maWcudHNcIjtcbmV4cG9ydCB0eXBlIHsgU2VuZGVyUG9saWN5LCBTbXRwQ29uZmlnLCBFbWFpbFBsdWdpbkNvbmZpZywgUmVzb2x2ZWRTZW5kZXIsIFJlc29sdmVkU210cENvbmZpZywgUmVzb2x2ZWRGaWxlQ29uZmlnLCBSZXNvbHZlZEVtYWlsQ29uZmlnIH0gZnJvbSBcIi4vc3JjL2NvbmZpZy50c1wiO1xuZXhwb3J0IHsgU0VORF9USU1FT1VUX01TLCBWRVJJRllfVElNRU9VVF9NUywgVkVSSUZZX0FUVEVNUFRTLCBNQVhfQVRUQUNITUVOVF9CWVRFUywgTUFYX0FUVEFDSE1FTlRTX1RPVEFMX0JZVEVTLCBNQVhfQVRUQUNITUVOVF9DT1VOVCwgTUFYX0JPRFlfQ0hBUlMsIEVNQUlMX1NFTkRfU0VUVElOR1MsIEVNQUlMX1ZFUklGWV9TRVRUSU5HUywgRU1BSUxfU0VOREVSU19TRVRUSU5HUyB9IGZyb20gXCIuL3NyYy9kZWZhdWx0cy50c1wiO1xuZXhwb3J0IHR5cGUgeyBFbWFpbEV4ZWN1dGVDb25maWcsIEVtYWlsRXhlY3V0aW9uU2V0dGluZ3MgfSBmcm9tIFwiLi9zcmMvZGVmYXVsdHMudHNcIjtcbmV4cG9ydCB7IGVzY2FwZUh0bWwgfSBmcm9tIFwiLi9zcmMvZW1haWwtaHRtbC50c1wiO1xuZXhwb3J0IHR5cGUgeyBFbWFpbEh0bWxPcHRpb25zIH0gZnJvbSBcIi4vc3JjL2VtYWlsLWh0bWwudHNcIjtcbmV4cG9ydCB7IG5vcm1hbGl6ZU1hcmtkb3duIH0gZnJvbSBcIi4vc3JjL21hcmtkb3duLnRzXCI7XG5leHBvcnQgeyBFbWFpbFBsdWdpbiwgZW1haWwgfSBmcm9tIFwiLi9zcmMvcGx1Z2luLnRzXCI7XG5leHBvcnQgeyBTWVNURU1fU0VOREVSX0xPQ0FMX1BBUlQgfSBmcm9tIFwiLi9zcmMvc2VuZGVyLnRzXCI7XG5leHBvcnQgeyBTRU5EX0VNQUlMX0RFU0NSSVBUSU9OIH0gZnJvbSBcIi4vc3JjL3Rvb2wudHNcIjtcbmV4cG9ydCB0eXBlIHsgRW1haWxUb29sT3B0aW9ucyB9IGZyb20gXCIuL3NyYy90b29sLnRzXCI7XG5leHBvcnQgdHlwZSB7IEVtYWlsRXhlY3V0b3IsIEVtYWlsUnVudGltZSwgU2VuZEVtYWlsT3B0aW9ucyB9IGZyb20gXCIuL3NyYy90cmFuc3BvcnQudHNcIjtcbiJdfQ==
|
package/lib/src/tool.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The `send_email` Mastra tool: approval
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* the
|
|
2
|
+
* The `send_email` Mastra tool: human approval is required by default, with an
|
|
3
|
+
* optional Mastra-native conditional approval function for caller-owned policy.
|
|
4
|
+
* Once allowed, the sender is resolved (explicit `from` config, else derived
|
|
5
|
+
* from the on-behalf-of user's email) and the message is dispatched through
|
|
6
|
+
* the shared SMTP transport.
|
|
7
7
|
*
|
|
8
8
|
* The sender derivation runs inside the AppKit user scope, so
|
|
9
9
|
* `getExecutionContext()` returns the OBO user whose local-part seeds
|
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
*
|
|
17
17
|
* @module
|
|
18
18
|
*/
|
|
19
|
+
import { email } from "@dbx-tools/shared-email";
|
|
20
|
+
import { type ToolAction } from "@mastra/core/tools";
|
|
19
21
|
/**
|
|
20
22
|
* The model-facing description of the send capability, shared by the Mastra
|
|
21
23
|
* {@link emailTool} and the AppKit `email.send` tool so both agents get the
|
|
@@ -30,6 +32,12 @@ export interface EmailToolOptions {
|
|
|
30
32
|
* the client about the new name.
|
|
31
33
|
*/
|
|
32
34
|
id?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Mastra-native static or per-call approval predicate. Defaults to `true`.
|
|
37
|
+
* Use a function or Classifier-backed policy to allow low-risk calls while
|
|
38
|
+
* retaining human review for uncertain ones.
|
|
39
|
+
*/
|
|
40
|
+
requireApproval?: ToolAction<email.EmailMessage, email.EmailResult>["requireApproval"];
|
|
33
41
|
}
|
|
34
42
|
/**
|
|
35
43
|
* Build the approval-gated `send_email` tool. Spread it into the agents
|
package/lib/src/tool.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The `send_email` Mastra tool: approval
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* the
|
|
2
|
+
* The `send_email` Mastra tool: human approval is required by default, with an
|
|
3
|
+
* optional Mastra-native conditional approval function for caller-owned policy.
|
|
4
|
+
* Once allowed, the sender is resolved (explicit `from` config, else derived
|
|
5
|
+
* from the on-behalf-of user's email) and the message is dispatched through
|
|
6
|
+
* the shared SMTP transport.
|
|
7
7
|
*
|
|
8
8
|
* The sender derivation runs inside the AppKit user scope, so
|
|
9
9
|
* `getExecutionContext()` returns the OBO user whose local-part seeds
|
|
@@ -31,8 +31,8 @@ const logger = log.logger("email/tool/send-email");
|
|
|
31
31
|
export const SEND_EMAIL_DESCRIPTION = string.toDescription(`
|
|
32
32
|
Send an email on the user's behalf. Pass one or more recipient
|
|
33
33
|
addresses (with optional cc / bcc and file attachments), a subject,
|
|
34
|
-
and a body; the
|
|
35
|
-
|
|
34
|
+
and a body; the configured approval policy runs before it goes out.
|
|
35
|
+
Use it only when the user
|
|
36
36
|
explicitly asks to send / forward / share something via email -
|
|
37
37
|
never autonomously. Compose whatever subject and body best fulfill
|
|
38
38
|
the user's request; the configured React Email template handles the
|
|
@@ -60,7 +60,7 @@ export function emailTool(opts = {}) {
|
|
|
60
60
|
description: SEND_EMAIL_DESCRIPTION,
|
|
61
61
|
inputSchema: email.emailMessageSchema,
|
|
62
62
|
outputSchema: email.emailResultSchema,
|
|
63
|
-
requireApproval: true,
|
|
63
|
+
requireApproval: opts.requireApproval ?? true,
|
|
64
64
|
execute: async (input, context) => {
|
|
65
65
|
const message = email.emailMessageSchema.parse(input);
|
|
66
66
|
const { config } = getEmailRuntime();
|
|
@@ -77,4 +77,4 @@ export function emailTool(opts = {}) {
|
|
|
77
77
|
},
|
|
78
78
|
});
|
|
79
79
|
}
|
|
80
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
80
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90b29sLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUVILE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDckQsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ2hELE9BQU8sRUFBRSxVQUFVLEVBQW1CLE1BQU0sb0JBQW9CLENBQUM7QUFDakUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxlQUFlLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFNUQsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO0FBRW5EOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBRyxNQUFNLENBQUMsYUFBYSxDQUFDOzs7Ozs7Ozs7Q0FTMUQsQ0FBQyxDQUFDO0FBa0JIOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUNILE1BQU0sVUFBVSxTQUFTLENBQUMsT0FBeUIsRUFBRTtJQUNuRCxPQUFPLFVBQVUsQ0FBQztRQUNoQixFQUFFLEVBQUUsSUFBSSxDQUFDLEVBQUUsSUFBSSxZQUFZO1FBQzNCLFdBQVcsRUFBRSxzQkFBc0I7UUFDbkMsV0FBVyxFQUFFLEtBQUssQ0FBQyxrQkFBa0I7UUFDckMsWUFBWSxFQUFFLEtBQUssQ0FBQyxpQkFBaUI7UUFDckMsZUFBZSxFQUFFLElBQUksQ0FBQyxlQUFlLElBQUksSUFBSTtRQUM3QyxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtZQUNoQyxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3RELE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxlQUFlLEVBQUUsQ0FBQztZQUNyQyxNQUFNLEdBQUcsR0FBRyxtQkFBbUIsRUFBRSxDQUFDO1lBQ2xDLE1BQU0sU0FBUyxHQUFHLGVBQWUsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztZQUNyRSxNQUFNLElBQUksR0FBRyxvQkFBb0IsQ0FBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFDckQsTUFBTSxNQUFNLEdBQUcsTUFBTSxTQUFTLENBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsV0FBVyxDQUFDLENBQUM7WUFDcEUsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUU7Z0JBQ2xCLEVBQUUsRUFBRSxNQUFNLENBQUMsU0FBUztnQkFDcEIsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJO2dCQUNqQixHQUFHLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7YUFDN0QsQ0FBQyxDQUFDO1lBQ0gsT0FBTyxNQUFNLENBQUM7UUFDaEIsQ0FBQztLQUNGLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFRoZSBgc2VuZF9lbWFpbGAgTWFzdHJhIHRvb2w6IGh1bWFuIGFwcHJvdmFsIGlzIHJlcXVpcmVkIGJ5IGRlZmF1bHQsIHdpdGggYW5cbiAqIG9wdGlvbmFsIE1hc3RyYS1uYXRpdmUgY29uZGl0aW9uYWwgYXBwcm92YWwgZnVuY3Rpb24gZm9yIGNhbGxlci1vd25lZCBwb2xpY3kuXG4gKiBPbmNlIGFsbG93ZWQsIHRoZSBzZW5kZXIgaXMgcmVzb2x2ZWQgKGV4cGxpY2l0IGBmcm9tYCBjb25maWcsIGVsc2UgZGVyaXZlZFxuICogZnJvbSB0aGUgb24tYmVoYWxmLW9mIHVzZXIncyBlbWFpbCkgYW5kIHRoZSBtZXNzYWdlIGlzIGRpc3BhdGNoZWQgdGhyb3VnaFxuICogdGhlIHNoYXJlZCBTTVRQIHRyYW5zcG9ydC5cbiAqXG4gKiBUaGUgc2VuZGVyIGRlcml2YXRpb24gcnVucyBpbnNpZGUgdGhlIEFwcEtpdCB1c2VyIHNjb3BlLCBzb1xuICogYGdldEV4ZWN1dGlvbkNvbnRleHQoKWAgcmV0dXJucyB0aGUgT0JPIHVzZXIgd2hvc2UgbG9jYWwtcGFydCBzZWVkc1xuICogdGhlIGFkZHJlc3MgKHNlZSB7QGxpbmsgZGVyaXZlU2VuZGVyQWRkcmVzc30pLlxuICpcbiAqIFRoZSBkaXNwYXRjaCBpdHNlbGYgZ29lcyB0aHJvdWdoIHRoZSBleGVjdXRvciB0aGUgcGx1Z2luIGluc3RhbGxzIG9uIHRoZVxuICogc2hhcmVkIHJ1bnRpbWUsIHNvIGEgc2VuZCBmcm9tIHRoaXMgdG9vbCBwaWNrcyB1cCB0aGUgc2FtZSByZXRyeSAvIHRpbWVvdXQgL1xuICogdGVsZW1ldHJ5IGNoYWluIGFzIG9uZSBmcm9tIHRoZSBBcHBLaXQgdG9vbC4gSW4gYSBNYXN0cmEgYXBwIHdpdGggbm8gQXBwS2l0XG4gKiBwbHVnaW4gcmVnaXN0ZXJlZCB0aGUgc2VuZCBzdGlsbCBydW5zLCBqdXN0IHdpdGhvdXQgaW50ZXJjZXB0b3JzLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBnZXRFeGVjdXRpb25Db250ZXh0IH0gZnJvbSBcIkBkYXRhYnJpY2tzL2FwcGtpdFwiO1xuaW1wb3J0IHsgbG9nLCBzdHJpbmcgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHsgZW1haWwgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtZW1haWxcIjtcbmltcG9ydCB7IGNyZWF0ZVRvb2wsIHR5cGUgVG9vbEFjdGlvbiB9IGZyb20gXCJAbWFzdHJhL2NvcmUvdG9vbHNcIjtcbmltcG9ydCB7IHJlc29sdmVTZW5kZXJBZGRyZXNzIH0gZnJvbSBcIi4vc2VuZGVyLnRzXCI7XG5pbXBvcnQgeyBnZXRFbWFpbFJ1bnRpbWUsIHNlbmRFbWFpbCB9IGZyb20gXCIuL3RyYW5zcG9ydC50c1wiO1xuXG5jb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwiZW1haWwvdG9vbC9zZW5kLWVtYWlsXCIpO1xuXG4vKipcbiAqIFRoZSBtb2RlbC1mYWNpbmcgZGVzY3JpcHRpb24gb2YgdGhlIHNlbmQgY2FwYWJpbGl0eSwgc2hhcmVkIGJ5IHRoZSBNYXN0cmFcbiAqIHtAbGluayBlbWFpbFRvb2x9IGFuZCB0aGUgQXBwS2l0IGBlbWFpbC5zZW5kYCB0b29sIHNvIGJvdGggYWdlbnRzIGdldCB0aGVcbiAqIHNhbWUgZ3VpZGFuY2UgYWJvdXQgYXBwcm92YWwgYW5kIHNjb3BlLlxuICovXG5leHBvcnQgY29uc3QgU0VORF9FTUFJTF9ERVNDUklQVElPTiA9IHN0cmluZy50b0Rlc2NyaXB0aW9uKGBcbiAgU2VuZCBhbiBlbWFpbCBvbiB0aGUgdXNlcidzIGJlaGFsZi4gUGFzcyBvbmUgb3IgbW9yZSByZWNpcGllbnRcbiAgYWRkcmVzc2VzICh3aXRoIG9wdGlvbmFsIGNjIC8gYmNjIGFuZCBmaWxlIGF0dGFjaG1lbnRzKSwgYSBzdWJqZWN0LFxuICBhbmQgYSBib2R5OyB0aGUgY29uZmlndXJlZCBhcHByb3ZhbCBwb2xpY3kgcnVucyBiZWZvcmUgaXQgZ29lcyBvdXQuXG4gIFVzZSBpdCBvbmx5IHdoZW4gdGhlIHVzZXJcbiAgZXhwbGljaXRseSBhc2tzIHRvIHNlbmQgLyBmb3J3YXJkIC8gc2hhcmUgc29tZXRoaW5nIHZpYSBlbWFpbCAtXG4gIG5ldmVyIGF1dG9ub21vdXNseS4gQ29tcG9zZSB3aGF0ZXZlciBzdWJqZWN0IGFuZCBib2R5IGJlc3QgZnVsZmlsbFxuICB0aGUgdXNlcidzIHJlcXVlc3Q7IHRoZSBjb25maWd1cmVkIFJlYWN0IEVtYWlsIHRlbXBsYXRlIGhhbmRsZXMgdGhlXG4gIHJlc3BvbnNpdmUgbGF5b3V0LCByaWNoIHByZXNlbnRhdGlvbiwgYW5kIGJyYW5kIHN0eWxpbmcuXG5gKTtcblxuLyoqIE9wdGlvbnMgYWNjZXB0ZWQgYnkge0BsaW5rIGVtYWlsVG9vbH0uICovXG5leHBvcnQgaW50ZXJmYWNlIEVtYWlsVG9vbE9wdGlvbnMge1xuICAvKipcbiAgICogT3ZlcnJpZGUgdGhlIHRvb2wgaWQuIERlZmF1bHRzIHRvIGBcInNlbmRfZW1haWxcImA7IHRoZSBjaGF0IFVJJ3NcbiAgICogYXBwcm92YWwgZ2F0ZSBrZXlzIG9mZiB0aGlzIGlkLCBzbyBrZWVwIGl0IHVubGVzcyB5b3UgYWxzbyB0ZWFjaFxuICAgKiB0aGUgY2xpZW50IGFib3V0IHRoZSBuZXcgbmFtZS5cbiAgICovXG4gIGlkPzogc3RyaW5nO1xuICAvKipcbiAgICogTWFzdHJhLW5hdGl2ZSBzdGF0aWMgb3IgcGVyLWNhbGwgYXBwcm92YWwgcHJlZGljYXRlLiBEZWZhdWx0cyB0byBgdHJ1ZWAuXG4gICAqIFVzZSBhIGZ1bmN0aW9uIG9yIENsYXNzaWZpZXItYmFja2VkIHBvbGljeSB0byBhbGxvdyBsb3ctcmlzayBjYWxscyB3aGlsZVxuICAgKiByZXRhaW5pbmcgaHVtYW4gcmV2aWV3IGZvciB1bmNlcnRhaW4gb25lcy5cbiAgICovXG4gIHJlcXVpcmVBcHByb3ZhbD86IFRvb2xBY3Rpb248ZW1haWwuRW1haWxNZXNzYWdlLCBlbWFpbC5FbWFpbFJlc3VsdD5bXCJyZXF1aXJlQXBwcm92YWxcIl07XG59XG5cbi8qKlxuICogQnVpbGQgdGhlIGFwcHJvdmFsLWdhdGVkIGBzZW5kX2VtYWlsYCB0b29sLiBTcHJlYWQgaXQgaW50byB0aGUgYWdlbnRzXG4gKiB0aGF0IHNob3VsZCBiZSBhYmxlIHRvIGRyYWZ0IG1haWw7IGl0IGlzIGludGVudGlvbmFsbHkgbm90IGluc3RhbGxlZFxuICogZXZlcnl3aGVyZS5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIGltcG9ydCB7IGVtYWlsVG9vbCB9IGZyb20gXCJAZGJ4LXRvb2xzL2VtYWlsXCI7XG4gKiBpbXBvcnQgeyBjcmVhdGVBZ2VudCB9IGZyb20gXCJAZGJ4LXRvb2xzL2FwcGtpdC1tYXN0cmFcIjtcbiAqXG4gKiBjb25zdCBzdXBwb3J0ID0gY3JlYXRlQWdlbnQoe1xuICogICBpbnN0cnVjdGlvbnM6IFwiLi4uXCIsXG4gKiAgIHRvb2xzOiAoKSA9PiAoeyBzZW5kX2VtYWlsOiBlbWFpbFRvb2woKSB9KSxcbiAqIH0pO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbWFpbFRvb2wob3B0czogRW1haWxUb29sT3B0aW9ucyA9IHt9KSB7XG4gIHJldHVybiBjcmVhdGVUb29sKHtcbiAgICBpZDogb3B0cy5pZCA/PyBcInNlbmRfZW1haWxcIixcbiAgICBkZXNjcmlwdGlvbjogU0VORF9FTUFJTF9ERVNDUklQVElPTixcbiAgICBpbnB1dFNjaGVtYTogZW1haWwuZW1haWxNZXNzYWdlU2NoZW1hLFxuICAgIG91dHB1dFNjaGVtYTogZW1haWwuZW1haWxSZXN1bHRTY2hlbWEsXG4gICAgcmVxdWlyZUFwcHJvdmFsOiBvcHRzLnJlcXVpcmVBcHByb3ZhbCA/PyB0cnVlLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChpbnB1dCwgY29udGV4dCkgPT4ge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IGVtYWlsLmVtYWlsTWVzc2FnZVNjaGVtYS5wYXJzZShpbnB1dCk7XG4gICAgICBjb25zdCB7IGNvbmZpZyB9ID0gZ2V0RW1haWxSdW50aW1lKCk7XG4gICAgICBjb25zdCBjdHggPSBnZXRFeGVjdXRpb25Db250ZXh0KCk7XG4gICAgICBjb25zdCB1c2VyRW1haWwgPSBcImlzVXNlckNvbnRleHRcIiBpbiBjdHggPyBjdHgudXNlckVtYWlsIDogdW5kZWZpbmVkO1xuICAgICAgY29uc3QgZnJvbSA9IHJlc29sdmVTZW5kZXJBZGRyZXNzKGNvbmZpZywgdXNlckVtYWlsKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHNlbmRFbWFpbChtZXNzYWdlLCBmcm9tLCBjb250ZXh0Py5hYm9ydFNpZ25hbCk7XG4gICAgICBsb2dnZXIuaW5mbyhcInNlbnRcIiwge1xuICAgICAgICB0bzogcmVzdWx0LnJlY2lwaWVudCxcbiAgICAgICAgZnJvbTogcmVzdWx0LmZyb20sXG4gICAgICAgIC4uLihyZXN1bHQubWVzc2FnZUlkID8geyBtZXNzYWdlSWQ6IHJlc3VsdC5tZXNzYWdlSWQgfSA6IHt9KSxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9LFxuICB9KTtcbn1cbiJdfQ==
|
package/package.json
CHANGED
|
@@ -28,12 +28,12 @@
|
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@databricks/appkit": "^0.60.0",
|
|
31
|
-
"@dbx-tools/appkit": "0.6.
|
|
32
|
-
"@dbx-tools/core": "0.6.
|
|
33
|
-
"@dbx-tools/shared-core": "0.6.
|
|
34
|
-
"@dbx-tools/shared-email": "0.6.
|
|
35
|
-
"@dbx-tools/shared-email-template": "0.6.
|
|
36
|
-
"@mastra/core": "1.
|
|
31
|
+
"@dbx-tools/appkit": "0.6.219",
|
|
32
|
+
"@dbx-tools/core": "0.6.219",
|
|
33
|
+
"@dbx-tools/shared-core": "0.6.219",
|
|
34
|
+
"@dbx-tools/shared-email": "0.6.219",
|
|
35
|
+
"@dbx-tools/shared-email-template": "0.6.219",
|
|
36
|
+
"@mastra/core": "1.71.0",
|
|
37
37
|
"@react-email/render": "^2.1.0",
|
|
38
38
|
"nodemailer": "^7.0.13",
|
|
39
39
|
"react": "~19.2.4",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"./package.json": "./package.json"
|
|
54
54
|
}
|
|
55
55
|
},
|
|
56
|
-
"version": "0.6.
|
|
56
|
+
"version": "0.6.219",
|
|
57
57
|
"types": "./lib/index.d.ts",
|
|
58
58
|
"type": "module",
|
|
59
59
|
"exports": {
|
package/src/tool.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The `send_email` Mastra tool: approval
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* the
|
|
2
|
+
* The `send_email` Mastra tool: human approval is required by default, with an
|
|
3
|
+
* optional Mastra-native conditional approval function for caller-owned policy.
|
|
4
|
+
* Once allowed, the sender is resolved (explicit `from` config, else derived
|
|
5
|
+
* from the on-behalf-of user's email) and the message is dispatched through
|
|
6
|
+
* the shared SMTP transport.
|
|
7
7
|
*
|
|
8
8
|
* The sender derivation runs inside the AppKit user scope, so
|
|
9
9
|
* `getExecutionContext()` returns the OBO user whose local-part seeds
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
import { getExecutionContext } from "@databricks/appkit";
|
|
21
21
|
import { log, string } from "@dbx-tools/shared-core";
|
|
22
22
|
import { email } from "@dbx-tools/shared-email";
|
|
23
|
-
import { createTool } from "@mastra/core/tools";
|
|
23
|
+
import { createTool, type ToolAction } from "@mastra/core/tools";
|
|
24
24
|
import { resolveSenderAddress } from "./sender.ts";
|
|
25
25
|
import { getEmailRuntime, sendEmail } from "./transport.ts";
|
|
26
26
|
|
|
@@ -34,8 +34,8 @@ const logger = log.logger("email/tool/send-email");
|
|
|
34
34
|
export const SEND_EMAIL_DESCRIPTION = string.toDescription(`
|
|
35
35
|
Send an email on the user's behalf. Pass one or more recipient
|
|
36
36
|
addresses (with optional cc / bcc and file attachments), a subject,
|
|
37
|
-
and a body; the
|
|
38
|
-
|
|
37
|
+
and a body; the configured approval policy runs before it goes out.
|
|
38
|
+
Use it only when the user
|
|
39
39
|
explicitly asks to send / forward / share something via email -
|
|
40
40
|
never autonomously. Compose whatever subject and body best fulfill
|
|
41
41
|
the user's request; the configured React Email template handles the
|
|
@@ -50,6 +50,12 @@ export interface EmailToolOptions {
|
|
|
50
50
|
* the client about the new name.
|
|
51
51
|
*/
|
|
52
52
|
id?: string;
|
|
53
|
+
/**
|
|
54
|
+
* Mastra-native static or per-call approval predicate. Defaults to `true`.
|
|
55
|
+
* Use a function or Classifier-backed policy to allow low-risk calls while
|
|
56
|
+
* retaining human review for uncertain ones.
|
|
57
|
+
*/
|
|
58
|
+
requireApproval?: ToolAction<email.EmailMessage, email.EmailResult>["requireApproval"];
|
|
53
59
|
}
|
|
54
60
|
|
|
55
61
|
/**
|
|
@@ -74,7 +80,7 @@ export function emailTool(opts: EmailToolOptions = {}) {
|
|
|
74
80
|
description: SEND_EMAIL_DESCRIPTION,
|
|
75
81
|
inputSchema: email.emailMessageSchema,
|
|
76
82
|
outputSchema: email.emailResultSchema,
|
|
77
|
-
requireApproval: true,
|
|
83
|
+
requireApproval: opts.requireApproval ?? true,
|
|
78
84
|
execute: async (input, context) => {
|
|
79
85
|
const message = email.emailMessageSchema.parse(input);
|
|
80
86
|
const { config } = getEmailRuntime();
|