@dbx-tools/email 0.6.218 → 0.6.220

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 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.218";
6
+ export const PACKAGE_VERSION = "0.6.220";
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.218";
2
+ export declare const PACKAGE_VERSION = "0.6.220";
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.218";
5
+ export const PACKAGE_VERSION = "0.6.220";
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxrQkFBa0IsQ0FBQztBQUNyRCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsU0FBUyxDQUFDO0FBQ3pDLE9BQU8sS0FBSyxLQUFLLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEMsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssUUFBUSxNQUFNLG1CQUFtQixDQUFDO0FBQzlDLE9BQU8sS0FBSyxTQUFTLE1BQU0scUJBQXFCLENBQUM7QUFDakQsT0FBTyxLQUFLLFFBQVEsTUFBTSxtQkFBbUIsQ0FBQztBQUM5QyxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssSUFBSSxNQUFNLGVBQWUsQ0FBQztBQUN0QyxPQUFPLEtBQUssU0FBUyxNQUFNLG9CQUFvQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxzQkFBc0IsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRWpHLE9BQU8sRUFBRSxlQUFlLEVBQUUsaUJBQWlCLEVBQUUsZUFBZSxFQUFFLG9CQUFvQixFQUFFLDJCQUEyQixFQUFFLG9CQUFvQixFQUFFLGNBQWMsRUFBRSxtQkFBbUIsRUFBRSxxQkFBcUIsRUFBRSxzQkFBc0IsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRXJQLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUVqRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUN0RCxPQUFPLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3JELE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNELE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGVBQWUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEdFTkVSQVRFRCBieSBwcm9qZW4gd2F0Y2ggLSBETyBOT1QgRURJVC5cbi8vIFJlZ2VuZXJhdGVkIGZyb20gdGhlIGV4cG9ydGluZyBtb2R1bGVzIGluIC4vc3JjLlxuLy8gSGFuZCBlZGl0cyBhcmUgb3ZlcndyaXR0ZW4gb24gdGhlIG5leHQgd2F0Y2g7IHRoaXMgZmlsZSBpcyByZWFkLW9ubHkuXG5cbmV4cG9ydCBjb25zdCBQQUNLQUdFX0lERU5USUZJRVIgPSBcIkBkYngtdG9vbHMvZW1haWxcIjtcbmV4cG9ydCBjb25zdCBQQUNLQUdFX1ZFUlNJT04gPSBcIjAuNi4yMThcIjtcbmV4cG9ydCAqIGFzIGJyYW5kIGZyb20gXCIuL3NyYy9icmFuZC50c1wiO1xuZXhwb3J0ICogYXMgY29uZmlnIGZyb20gXCIuL3NyYy9jb25maWcudHNcIjtcbmV4cG9ydCAqIGFzIGRlZmF1bHRzIGZyb20gXCIuL3NyYy9kZWZhdWx0cy50c1wiO1xuZXhwb3J0ICogYXMgZW1haWxIdG1sIGZyb20gXCIuL3NyYy9lbWFpbC1odG1sLnRzXCI7XG5leHBvcnQgKiBhcyBtYXJrZG93biBmcm9tIFwiLi9zcmMvbWFya2Rvd24udHNcIjtcbmV4cG9ydCAqIGFzIG91dGJveCBmcm9tIFwiLi9zcmMvb3V0Ym94LnRzXCI7XG5leHBvcnQgKiBhcyBwbHVnaW4gZnJvbSBcIi4vc3JjL3BsdWdpbi50c1wiO1xuZXhwb3J0ICogYXMgc2VuZGVyIGZyb20gXCIuL3NyYy9zZW5kZXIudHNcIjtcbmV4cG9ydCAqIGFzIHRvb2wgZnJvbSBcIi4vc3JjL3Rvb2wudHNcIjtcbmV4cG9ydCAqIGFzIHRyYW5zcG9ydCBmcm9tIFwiLi9zcmMvdHJhbnNwb3J0LnRzXCI7XG5leHBvcnQgeyBERUZBVUxUX1NNVFBfUE9SVCwgSU1QTElDSVRfVExTX1NNVFBfUE9SVCwgRU1BSUxfQ09ORklHX1NDSEVNQSB9IGZyb20gXCIuL3NyYy9jb25maWcudHNcIjtcbmV4cG9ydCB0eXBlIHsgU2VuZGVyUG9saWN5LCBTbXRwQ29uZmlnLCBFbWFpbFBsdWdpbkNvbmZpZywgUmVzb2x2ZWRTZW5kZXIsIFJlc29sdmVkU210cENvbmZpZywgUmVzb2x2ZWRGaWxlQ29uZmlnLCBSZXNvbHZlZEVtYWlsQ29uZmlnIH0gZnJvbSBcIi4vc3JjL2NvbmZpZy50c1wiO1xuZXhwb3J0IHsgU0VORF9USU1FT1VUX01TLCBWRVJJRllfVElNRU9VVF9NUywgVkVSSUZZX0FUVEVNUFRTLCBNQVhfQVRUQUNITUVOVF9CWVRFUywgTUFYX0FUVEFDSE1FTlRTX1RPVEFMX0JZVEVTLCBNQVhfQVRUQUNITUVOVF9DT1VOVCwgTUFYX0JPRFlfQ0hBUlMsIEVNQUlMX1NFTkRfU0VUVElOR1MsIEVNQUlMX1ZFUklGWV9TRVRUSU5HUywgRU1BSUxfU0VOREVSU19TRVRUSU5HUyB9IGZyb20gXCIuL3NyYy9kZWZhdWx0cy50c1wiO1xuZXhwb3J0IHR5cGUgeyBFbWFpbEV4ZWN1dGVDb25maWcsIEVtYWlsRXhlY3V0aW9uU2V0dGluZ3MgfSBmcm9tIFwiLi9zcmMvZGVmYXVsdHMudHNcIjtcbmV4cG9ydCB7IGVzY2FwZUh0bWwgfSBmcm9tIFwiLi9zcmMvZW1haWwtaHRtbC50c1wiO1xuZXhwb3J0IHR5cGUgeyBFbWFpbEh0bWxPcHRpb25zIH0gZnJvbSBcIi4vc3JjL2VtYWlsLWh0bWwudHNcIjtcbmV4cG9ydCB7IG5vcm1hbGl6ZU1hcmtkb3duIH0gZnJvbSBcIi4vc3JjL21hcmtkb3duLnRzXCI7XG5leHBvcnQgeyBFbWFpbFBsdWdpbiwgZW1haWwgfSBmcm9tIFwiLi9zcmMvcGx1Z2luLnRzXCI7XG5leHBvcnQgeyBTWVNURU1fU0VOREVSX0xPQ0FMX1BBUlQgfSBmcm9tIFwiLi9zcmMvc2VuZGVyLnRzXCI7XG5leHBvcnQgeyBTRU5EX0VNQUlMX0RFU0NSSVBUSU9OIH0gZnJvbSBcIi4vc3JjL3Rvb2wudHNcIjtcbmV4cG9ydCB0eXBlIHsgRW1haWxUb29sT3B0aW9ucyB9IGZyb20gXCIuL3NyYy90b29sLnRzXCI7XG5leHBvcnQgdHlwZSB7IEVtYWlsRXhlY3V0b3IsIEVtYWlsUnVudGltZSwgU2VuZEVtYWlsT3B0aW9ucyB9IGZyb20gXCIuL3NyYy90cmFuc3BvcnQudHNcIjtcbiJdfQ==
23
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxrQkFBa0IsQ0FBQztBQUNyRCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsU0FBUyxDQUFDO0FBQ3pDLE9BQU8sS0FBSyxLQUFLLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEMsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssUUFBUSxNQUFNLG1CQUFtQixDQUFDO0FBQzlDLE9BQU8sS0FBSyxTQUFTLE1BQU0scUJBQXFCLENBQUM7QUFDakQsT0FBTyxLQUFLLFFBQVEsTUFBTSxtQkFBbUIsQ0FBQztBQUM5QyxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssSUFBSSxNQUFNLGVBQWUsQ0FBQztBQUN0QyxPQUFPLEtBQUssU0FBUyxNQUFNLG9CQUFvQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxzQkFBc0IsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRWpHLE9BQU8sRUFBRSxlQUFlLEVBQUUsaUJBQWlCLEVBQUUsZUFBZSxFQUFFLG9CQUFvQixFQUFFLDJCQUEyQixFQUFFLG9CQUFvQixFQUFFLGNBQWMsRUFBRSxtQkFBbUIsRUFBRSxxQkFBcUIsRUFBRSxzQkFBc0IsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRXJQLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUVqRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUN0RCxPQUFPLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3JELE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNELE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGVBQWUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEdFTkVSQVRFRCBieSBwcm9qZW4gd2F0Y2ggLSBETyBOT1QgRURJVC5cbi8vIFJlZ2VuZXJhdGVkIGZyb20gdGhlIGV4cG9ydGluZyBtb2R1bGVzIGluIC4vc3JjLlxuLy8gSGFuZCBlZGl0cyBhcmUgb3ZlcndyaXR0ZW4gb24gdGhlIG5leHQgd2F0Y2g7IHRoaXMgZmlsZSBpcyByZWFkLW9ubHkuXG5cbmV4cG9ydCBjb25zdCBQQUNLQUdFX0lERU5USUZJRVIgPSBcIkBkYngtdG9vbHMvZW1haWxcIjtcbmV4cG9ydCBjb25zdCBQQUNLQUdFX1ZFUlNJT04gPSBcIjAuNi4yMjBcIjtcbmV4cG9ydCAqIGFzIGJyYW5kIGZyb20gXCIuL3NyYy9icmFuZC50c1wiO1xuZXhwb3J0ICogYXMgY29uZmlnIGZyb20gXCIuL3NyYy9jb25maWcudHNcIjtcbmV4cG9ydCAqIGFzIGRlZmF1bHRzIGZyb20gXCIuL3NyYy9kZWZhdWx0cy50c1wiO1xuZXhwb3J0ICogYXMgZW1haWxIdG1sIGZyb20gXCIuL3NyYy9lbWFpbC1odG1sLnRzXCI7XG5leHBvcnQgKiBhcyBtYXJrZG93biBmcm9tIFwiLi9zcmMvbWFya2Rvd24udHNcIjtcbmV4cG9ydCAqIGFzIG91dGJveCBmcm9tIFwiLi9zcmMvb3V0Ym94LnRzXCI7XG5leHBvcnQgKiBhcyBwbHVnaW4gZnJvbSBcIi4vc3JjL3BsdWdpbi50c1wiO1xuZXhwb3J0ICogYXMgc2VuZGVyIGZyb20gXCIuL3NyYy9zZW5kZXIudHNcIjtcbmV4cG9ydCAqIGFzIHRvb2wgZnJvbSBcIi4vc3JjL3Rvb2wudHNcIjtcbmV4cG9ydCAqIGFzIHRyYW5zcG9ydCBmcm9tIFwiLi9zcmMvdHJhbnNwb3J0LnRzXCI7XG5leHBvcnQgeyBERUZBVUxUX1NNVFBfUE9SVCwgSU1QTElDSVRfVExTX1NNVFBfUE9SVCwgRU1BSUxfQ09ORklHX1NDSEVNQSB9IGZyb20gXCIuL3NyYy9jb25maWcudHNcIjtcbmV4cG9ydCB0eXBlIHsgU2VuZGVyUG9saWN5LCBTbXRwQ29uZmlnLCBFbWFpbFBsdWdpbkNvbmZpZywgUmVzb2x2ZWRTZW5kZXIsIFJlc29sdmVkU210cENvbmZpZywgUmVzb2x2ZWRGaWxlQ29uZmlnLCBSZXNvbHZlZEVtYWlsQ29uZmlnIH0gZnJvbSBcIi4vc3JjL2NvbmZpZy50c1wiO1xuZXhwb3J0IHsgU0VORF9USU1FT1VUX01TLCBWRVJJRllfVElNRU9VVF9NUywgVkVSSUZZX0FUVEVNUFRTLCBNQVhfQVRUQUNITUVOVF9CWVRFUywgTUFYX0FUVEFDSE1FTlRTX1RPVEFMX0JZVEVTLCBNQVhfQVRUQUNITUVOVF9DT1VOVCwgTUFYX0JPRFlfQ0hBUlMsIEVNQUlMX1NFTkRfU0VUVElOR1MsIEVNQUlMX1ZFUklGWV9TRVRUSU5HUywgRU1BSUxfU0VOREVSU19TRVRUSU5HUyB9IGZyb20gXCIuL3NyYy9kZWZhdWx0cy50c1wiO1xuZXhwb3J0IHR5cGUgeyBFbWFpbEV4ZWN1dGVDb25maWcsIEVtYWlsRXhlY3V0aW9uU2V0dGluZ3MgfSBmcm9tIFwiLi9zcmMvZGVmYXVsdHMudHNcIjtcbmV4cG9ydCB7IGVzY2FwZUh0bWwgfSBmcm9tIFwiLi9zcmMvZW1haWwtaHRtbC50c1wiO1xuZXhwb3J0IHR5cGUgeyBFbWFpbEh0bWxPcHRpb25zIH0gZnJvbSBcIi4vc3JjL2VtYWlsLWh0bWwudHNcIjtcbmV4cG9ydCB7IG5vcm1hbGl6ZU1hcmtkb3duIH0gZnJvbSBcIi4vc3JjL21hcmtkb3duLnRzXCI7XG5leHBvcnQgeyBFbWFpbFBsdWdpbiwgZW1haWwgfSBmcm9tIFwiLi9zcmMvcGx1Z2luLnRzXCI7XG5leHBvcnQgeyBTWVNURU1fU0VOREVSX0xPQ0FMX1BBUlQgfSBmcm9tIFwiLi9zcmMvc2VuZGVyLnRzXCI7XG5leHBvcnQgeyBTRU5EX0VNQUlMX0RFU0NSSVBUSU9OIH0gZnJvbSBcIi4vc3JjL3Rvb2wudHNcIjtcbmV4cG9ydCB0eXBlIHsgRW1haWxUb29sT3B0aW9ucyB9IGZyb20gXCIuL3NyYy90b29sLnRzXCI7XG5leHBvcnQgdHlwZSB7IEVtYWlsRXhlY3V0b3IsIEVtYWlsUnVudGltZSwgU2VuZEVtYWlsT3B0aW9ucyB9IGZyb20gXCIuL3NyYy90cmFuc3BvcnQudHNcIjtcbiJdfQ==
package/lib/src/tool.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  /**
2
- * The `send_email` Mastra tool: approval-gated so a model can draft a
3
- * message freely but nothing leaves the building until a human clicks
4
- * Approve in the chat UI. On approval the sender is resolved (explicit
5
- * `from` config, else derived from the on-behalf-of user's email) and
6
- * the message is dispatched through the shared SMTP transport.
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-gated so a model can draft a
3
- * message freely but nothing leaves the building until a human clicks
4
- * Approve in the chat UI. On approval the sender is resolved (explicit
5
- * `from` config, else derived from the on-behalf-of user's email) and
6
- * the message is dispatched through the shared SMTP transport.
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 user is prompted to approve the send before it goes
35
- out (this tool is approval-gated). Use it only when the user
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90b29sLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUVILE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDckQsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ2hELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDbkQsT0FBTyxFQUFFLGVBQWUsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU1RCxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLHVCQUF1QixDQUFDLENBQUM7QUFFbkQ7Ozs7R0FJRztBQUNILE1BQU0sQ0FBQyxNQUFNLHNCQUFzQixHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUM7Ozs7Ozs7OztDQVMxRCxDQUFDLENBQUM7QUFZSDs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFDSCxNQUFNLFVBQVUsU0FBUyxDQUFDLE9BQXlCLEVBQUU7SUFDbkQsT0FBTyxVQUFVLENBQUM7UUFDaEIsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFLElBQUksWUFBWTtRQUMzQixXQUFXLEVBQUUsc0JBQXNCO1FBQ25DLFdBQVcsRUFBRSxLQUFLLENBQUMsa0JBQWtCO1FBQ3JDLFlBQVksRUFBRSxLQUFLLENBQUMsaUJBQWlCO1FBQ3JDLGVBQWUsRUFBRSxJQUFJO1FBQ3JCLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFO1lBQ2hDLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDdEQsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLGVBQWUsRUFBRSxDQUFDO1lBQ3JDLE1BQU0sR0FBRyxHQUFHLG1CQUFtQixFQUFFLENBQUM7WUFDbEMsTUFBTSxTQUFTLEdBQUcsZUFBZSxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1lBQ3JFLE1BQU0sSUFBSSxHQUFHLG9CQUFvQixDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQztZQUNyRCxNQUFNLE1BQU0sR0FBRyxNQUFNLFNBQVMsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxXQUFXLENBQUMsQ0FBQztZQUNwRSxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRTtnQkFDbEIsRUFBRSxFQUFFLE1BQU0sQ0FBQyxTQUFTO2dCQUNwQixJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUk7Z0JBQ2pCLEdBQUcsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLFNBQVMsRUFBRSxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQzthQUM3RCxDQUFDLENBQUM7WUFDSCxPQUFPLE1BQU0sQ0FBQztRQUNoQixDQUFDO0tBQ0YsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVGhlIGBzZW5kX2VtYWlsYCBNYXN0cmEgdG9vbDogYXBwcm92YWwtZ2F0ZWQgc28gYSBtb2RlbCBjYW4gZHJhZnQgYVxuICogbWVzc2FnZSBmcmVlbHkgYnV0IG5vdGhpbmcgbGVhdmVzIHRoZSBidWlsZGluZyB1bnRpbCBhIGh1bWFuIGNsaWNrc1xuICogQXBwcm92ZSBpbiB0aGUgY2hhdCBVSS4gT24gYXBwcm92YWwgdGhlIHNlbmRlciBpcyByZXNvbHZlZCAoZXhwbGljaXRcbiAqIGBmcm9tYCBjb25maWcsIGVsc2UgZGVyaXZlZCBmcm9tIHRoZSBvbi1iZWhhbGYtb2YgdXNlcidzIGVtYWlsKSBhbmRcbiAqIHRoZSBtZXNzYWdlIGlzIGRpc3BhdGNoZWQgdGhyb3VnaCB0aGUgc2hhcmVkIFNNVFAgdHJhbnNwb3J0LlxuICpcbiAqIFRoZSBzZW5kZXIgZGVyaXZhdGlvbiBydW5zIGluc2lkZSB0aGUgQXBwS2l0IHVzZXIgc2NvcGUsIHNvXG4gKiBgZ2V0RXhlY3V0aW9uQ29udGV4dCgpYCByZXR1cm5zIHRoZSBPQk8gdXNlciB3aG9zZSBsb2NhbC1wYXJ0IHNlZWRzXG4gKiB0aGUgYWRkcmVzcyAoc2VlIHtAbGluayBkZXJpdmVTZW5kZXJBZGRyZXNzfSkuXG4gKlxuICogVGhlIGRpc3BhdGNoIGl0c2VsZiBnb2VzIHRocm91Z2ggdGhlIGV4ZWN1dG9yIHRoZSBwbHVnaW4gaW5zdGFsbHMgb24gdGhlXG4gKiBzaGFyZWQgcnVudGltZSwgc28gYSBzZW5kIGZyb20gdGhpcyB0b29sIHBpY2tzIHVwIHRoZSBzYW1lIHJldHJ5IC8gdGltZW91dCAvXG4gKiB0ZWxlbWV0cnkgY2hhaW4gYXMgb25lIGZyb20gdGhlIEFwcEtpdCB0b29sLiBJbiBhIE1hc3RyYSBhcHAgd2l0aCBubyBBcHBLaXRcbiAqIHBsdWdpbiByZWdpc3RlcmVkIHRoZSBzZW5kIHN0aWxsIHJ1bnMsIGp1c3Qgd2l0aG91dCBpbnRlcmNlcHRvcnMuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IGdldEV4ZWN1dGlvbkNvbnRleHQgfSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG5pbXBvcnQgeyBsb2csIHN0cmluZyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgeyBlbWFpbCB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1lbWFpbFwiO1xuaW1wb3J0IHsgY3JlYXRlVG9vbCB9IGZyb20gXCJAbWFzdHJhL2NvcmUvdG9vbHNcIjtcbmltcG9ydCB7IHJlc29sdmVTZW5kZXJBZGRyZXNzIH0gZnJvbSBcIi4vc2VuZGVyLnRzXCI7XG5pbXBvcnQgeyBnZXRFbWFpbFJ1bnRpbWUsIHNlbmRFbWFpbCB9IGZyb20gXCIuL3RyYW5zcG9ydC50c1wiO1xuXG5jb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwiZW1haWwvdG9vbC9zZW5kLWVtYWlsXCIpO1xuXG4vKipcbiAqIFRoZSBtb2RlbC1mYWNpbmcgZGVzY3JpcHRpb24gb2YgdGhlIHNlbmQgY2FwYWJpbGl0eSwgc2hhcmVkIGJ5IHRoZSBNYXN0cmFcbiAqIHtAbGluayBlbWFpbFRvb2x9IGFuZCB0aGUgQXBwS2l0IGBlbWFpbC5zZW5kYCB0b29sIHNvIGJvdGggYWdlbnRzIGdldCB0aGVcbiAqIHNhbWUgZ3VpZGFuY2UgYWJvdXQgYXBwcm92YWwgYW5kIHNjb3BlLlxuICovXG5leHBvcnQgY29uc3QgU0VORF9FTUFJTF9ERVNDUklQVElPTiA9IHN0cmluZy50b0Rlc2NyaXB0aW9uKGBcbiAgU2VuZCBhbiBlbWFpbCBvbiB0aGUgdXNlcidzIGJlaGFsZi4gUGFzcyBvbmUgb3IgbW9yZSByZWNpcGllbnRcbiAgYWRkcmVzc2VzICh3aXRoIG9wdGlvbmFsIGNjIC8gYmNjIGFuZCBmaWxlIGF0dGFjaG1lbnRzKSwgYSBzdWJqZWN0LFxuICBhbmQgYSBib2R5OyB0aGUgdXNlciBpcyBwcm9tcHRlZCB0byBhcHByb3ZlIHRoZSBzZW5kIGJlZm9yZSBpdCBnb2VzXG4gIG91dCAodGhpcyB0b29sIGlzIGFwcHJvdmFsLWdhdGVkKS4gVXNlIGl0IG9ubHkgd2hlbiB0aGUgdXNlclxuICBleHBsaWNpdGx5IGFza3MgdG8gc2VuZCAvIGZvcndhcmQgLyBzaGFyZSBzb21ldGhpbmcgdmlhIGVtYWlsIC1cbiAgbmV2ZXIgYXV0b25vbW91c2x5LiBDb21wb3NlIHdoYXRldmVyIHN1YmplY3QgYW5kIGJvZHkgYmVzdCBmdWxmaWxsXG4gIHRoZSB1c2VyJ3MgcmVxdWVzdDsgdGhlIGNvbmZpZ3VyZWQgUmVhY3QgRW1haWwgdGVtcGxhdGUgaGFuZGxlcyB0aGVcbiAgcmVzcG9uc2l2ZSBsYXlvdXQsIHJpY2ggcHJlc2VudGF0aW9uLCBhbmQgYnJhbmQgc3R5bGluZy5cbmApO1xuXG4vKiogT3B0aW9ucyBhY2NlcHRlZCBieSB7QGxpbmsgZW1haWxUb29sfS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRW1haWxUb29sT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBPdmVycmlkZSB0aGUgdG9vbCBpZC4gRGVmYXVsdHMgdG8gYFwic2VuZF9lbWFpbFwiYDsgdGhlIGNoYXQgVUknc1xuICAgKiBhcHByb3ZhbCBnYXRlIGtleXMgb2ZmIHRoaXMgaWQsIHNvIGtlZXAgaXQgdW5sZXNzIHlvdSBhbHNvIHRlYWNoXG4gICAqIHRoZSBjbGllbnQgYWJvdXQgdGhlIG5ldyBuYW1lLlxuICAgKi9cbiAgaWQ/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQnVpbGQgdGhlIGFwcHJvdmFsLWdhdGVkIGBzZW5kX2VtYWlsYCB0b29sLiBTcHJlYWQgaXQgaW50byB0aGUgYWdlbnRzXG4gKiB0aGF0IHNob3VsZCBiZSBhYmxlIHRvIGRyYWZ0IG1haWw7IGl0IGlzIGludGVudGlvbmFsbHkgbm90IGluc3RhbGxlZFxuICogZXZlcnl3aGVyZS5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIGltcG9ydCB7IGVtYWlsVG9vbCB9IGZyb20gXCJAZGJ4LXRvb2xzL2VtYWlsXCI7XG4gKiBpbXBvcnQgeyBjcmVhdGVBZ2VudCB9IGZyb20gXCJAZGJ4LXRvb2xzL2FwcGtpdC1tYXN0cmFcIjtcbiAqXG4gKiBjb25zdCBzdXBwb3J0ID0gY3JlYXRlQWdlbnQoe1xuICogICBpbnN0cnVjdGlvbnM6IFwiLi4uXCIsXG4gKiAgIHRvb2xzOiAoKSA9PiAoeyBzZW5kX2VtYWlsOiBlbWFpbFRvb2woKSB9KSxcbiAqIH0pO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbWFpbFRvb2wob3B0czogRW1haWxUb29sT3B0aW9ucyA9IHt9KSB7XG4gIHJldHVybiBjcmVhdGVUb29sKHtcbiAgICBpZDogb3B0cy5pZCA/PyBcInNlbmRfZW1haWxcIixcbiAgICBkZXNjcmlwdGlvbjogU0VORF9FTUFJTF9ERVNDUklQVElPTixcbiAgICBpbnB1dFNjaGVtYTogZW1haWwuZW1haWxNZXNzYWdlU2NoZW1hLFxuICAgIG91dHB1dFNjaGVtYTogZW1haWwuZW1haWxSZXN1bHRTY2hlbWEsXG4gICAgcmVxdWlyZUFwcHJvdmFsOiB0cnVlLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChpbnB1dCwgY29udGV4dCkgPT4ge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IGVtYWlsLmVtYWlsTWVzc2FnZVNjaGVtYS5wYXJzZShpbnB1dCk7XG4gICAgICBjb25zdCB7IGNvbmZpZyB9ID0gZ2V0RW1haWxSdW50aW1lKCk7XG4gICAgICBjb25zdCBjdHggPSBnZXRFeGVjdXRpb25Db250ZXh0KCk7XG4gICAgICBjb25zdCB1c2VyRW1haWwgPSBcImlzVXNlckNvbnRleHRcIiBpbiBjdHggPyBjdHgudXNlckVtYWlsIDogdW5kZWZpbmVkO1xuICAgICAgY29uc3QgZnJvbSA9IHJlc29sdmVTZW5kZXJBZGRyZXNzKGNvbmZpZywgdXNlckVtYWlsKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHNlbmRFbWFpbChtZXNzYWdlLCBmcm9tLCBjb250ZXh0Py5hYm9ydFNpZ25hbCk7XG4gICAgICBsb2dnZXIuaW5mbyhcInNlbnRcIiwge1xuICAgICAgICB0bzogcmVzdWx0LnJlY2lwaWVudCxcbiAgICAgICAgZnJvbTogcmVzdWx0LmZyb20sXG4gICAgICAgIC4uLihyZXN1bHQubWVzc2FnZUlkID8geyBtZXNzYWdlSWQ6IHJlc3VsdC5tZXNzYWdlSWQgfSA6IHt9KSxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9LFxuICB9KTtcbn1cbiJdfQ==
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.218",
32
- "@dbx-tools/core": "0.6.218",
33
- "@dbx-tools/shared-core": "0.6.218",
34
- "@dbx-tools/shared-email": "0.6.218",
35
- "@dbx-tools/shared-email-template": "0.6.218",
36
- "@mastra/core": "1.67.0",
31
+ "@dbx-tools/appkit": "0.6.220",
32
+ "@dbx-tools/core": "0.6.220",
33
+ "@dbx-tools/shared-core": "0.6.220",
34
+ "@dbx-tools/shared-email": "0.6.220",
35
+ "@dbx-tools/shared-email-template": "0.6.220",
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.218",
56
+ "version": "0.6.220",
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-gated so a model can draft a
3
- * message freely but nothing leaves the building until a human clicks
4
- * Approve in the chat UI. On approval the sender is resolved (explicit
5
- * `from` config, else derived from the on-behalf-of user's email) and
6
- * the message is dispatched through the shared SMTP transport.
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 user is prompted to approve the send before it goes
38
- out (this tool is approval-gated). Use it only when the user
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();