@mindstudio-ai/agent 0.1.109 → 0.1.110

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/dist/index.d.ts CHANGED
@@ -2359,7 +2359,7 @@ interface SearchRan {
2359
2359
  * vector, so they take effect on the next call and cost nothing. Anything that
2360
2360
  * would require rebuilding the corpus — chunking, the embedding model, whether
2361
2361
  * chunks are contextualized — is a property of the data source, configured
2362
- * with `mindstudio-prod datasources config` rather than passed here.
2362
+ * with `remy-admin datasources config` rather than passed here.
2363
2363
  *
2364
2364
  * The defaults come from the data source's own configuration, so most callers
2365
2365
  * should pass nothing.
@@ -2869,12 +2869,16 @@ interface Analytics {
2869
2869
  }
2870
2870
 
2871
2871
  /**
2872
- * The `email` namespace: read and manage your app's OWN outbound email.
2872
+ * The `email` namespace: send, read and manage your app's OWN outbound email.
2873
2873
  *
2874
- * Sending is not here — that's the `sendEmail` action
2875
- * (`mindstudio.sendEmail({...})`). This namespace is everything *after* the send:
2876
- * what happened to each message, how a campaign performed, and who has
2877
- * unsubscribed.
2874
+ * `email.send()` is the send path. The older `mindstudio.sendEmail({...})` action
2875
+ * still works and shares exactly the same implementation, so nothing breaks — but
2876
+ * `send()` is the one to reach for: it returns a proper receipt (including the
2877
+ * `batchId` you read stats back with) and it lives alongside everything you do
2878
+ * with the result.
2879
+ *
2880
+ * The rest of the namespace is everything *after* the send: what happened to each
2881
+ * message, how a campaign performed, and who has unsubscribed.
2878
2882
  *
2879
2883
  * The point is that you can build your own email admin screen inside your own app
2880
2884
  * and never open the MindStudio dashboard. So this deliberately includes the
@@ -2882,7 +2886,7 @@ interface Analytics {
2882
2886
  * unsubscribe list, this can do too.
2883
2887
  *
2884
2888
  * Every call is scoped to the executing app by its request token; there is no
2885
- * appId parameter and no way to read another app's mail.
2889
+ * appId parameter and no way to read or send as another app.
2886
2890
  */
2887
2891
  /** Where a message got to. See `EmailMessage.status`. */
2888
2892
  type EmailMessageStatus =
@@ -3018,7 +3022,149 @@ interface EmailWindowOptions {
3018
3022
  start?: string | Date;
3019
3023
  end?: string | Date;
3020
3024
  }
3025
+ /**
3026
+ * How a message body is interpreted.
3027
+ *
3028
+ * `auto` (the default) sniffs it: something that looks like HTML is sent as HTML,
3029
+ * anything else is rendered from Markdown. Every message goes out multipart with a
3030
+ * plain-text alternative derived from the body, which mail providers reward.
3031
+ */
3032
+ type EmailBodyType = 'auto' | 'html' | 'markdown' | 'text';
3033
+ interface EmailAttachmentInput {
3034
+ url: string;
3035
+ /** Displayed filename. Derived from the URL when omitted. */
3036
+ filename?: string;
3037
+ contentType?: string;
3038
+ }
3039
+ interface EmailSendOptions {
3040
+ /** Visible recipients. Optional only if you supply `cc` or `bcc`. */
3041
+ to?: string | string[];
3042
+ cc?: string | string[];
3043
+ /**
3044
+ * Hidden recipients. With no `to`/`cc`, the To: header is addressed to your
3045
+ * app's own sender — the standard "undisclosed recipients" pattern — so
3046
+ * recipients can't see each other.
3047
+ */
3048
+ bcc?: string | string[];
3049
+ subject: string;
3050
+ /** Plain text, Markdown, or HTML. See {@link EmailBodyType}. */
3051
+ body: string;
3052
+ bodyType?: EmailBodyType;
3053
+ /** Your own plain-text alternative, instead of the auto-derived one. */
3054
+ text?: string;
3055
+ attachments?: Array<string | EmailAttachmentInput>;
3056
+ /**
3057
+ * Sender handle — only if your app has a custom domain or platform subdomain.
3058
+ * `"support"`, `"support@your-domain.com"`, or `"Name <support@your-domain.com>"`.
3059
+ * The domain must be one your app owns or the send fails.
3060
+ */
3061
+ from?: string;
3062
+ replyTo?: string;
3063
+ /** Message-ID this replies to, for threading in a shared inbox. */
3064
+ inReplyTo?: string;
3065
+ /** Prior Message-IDs in the thread. */
3066
+ references?: string[];
3067
+ /**
3068
+ * **Defaults to `marketing`**, which is the consequential choice here.
3069
+ *
3070
+ * `marketing` attaches a one-click unsubscribe header pointing at your own
3071
+ * domain and skips anyone who previously unsubscribed from your app. Because
3072
+ * that link is per-recipient, a marketing send delivers one separate message per
3073
+ * recipient and `cc`/`bcc` are folded into that list — so they come back empty.
3074
+ *
3075
+ * `transactional` is for receipts, alerts and password resets: no unsubscribe
3076
+ * header, the unsubscribe list is ignored, and `cc`/`bcc` stay on one shared
3077
+ * message. Use it whenever cc/bcc semantics actually matter.
3078
+ */
3079
+ category?: 'transactional' | 'marketing';
3080
+ /**
3081
+ * Groups this send's per-recipient rows into one blast. Pass your own campaign
3082
+ * id (1–64 printable chars) to join our delivery stats onto your own tables with
3083
+ * no mapping; one is generated when omitted, and it's always returned.
3084
+ */
3085
+ batchId?: string;
3086
+ }
3087
+ interface EmailSendResult {
3088
+ /** Addresses the message went to. */
3089
+ recipients: string[];
3090
+ /** Always empty for a marketing send — see `category`. */
3091
+ cc: string[];
3092
+ /** Always empty for a marketing send — see `category`. */
3093
+ bcc: string[];
3094
+ /** The resolved sender it went out as. */
3095
+ from: string;
3096
+ /**
3097
+ * Recipients skipped because they had unsubscribed from your app. **Not an
3098
+ * error** — the send succeeded and we honoured their opt-out. Always empty for
3099
+ * a transactional send.
3100
+ *
3101
+ * Worth surfacing to whoever triggered the send: "sent to 48 of 50, 2
3102
+ * unsubscribed" is the honest report, and silence here is what makes people
3103
+ * think mail vanished.
3104
+ */
3105
+ suppressed: string[];
3106
+ /** Read stats back with `email.batch(batchId)`. */
3107
+ batchId: string;
3108
+ }
3109
+ /** Your app's sending allowance for the current window. */
3110
+ interface EmailQuota {
3111
+ /** What the numbers count — `recipients`. */
3112
+ unit: string;
3113
+ window: 'day' | 'month' | 'total';
3114
+ /** `null` means unlimited. */
3115
+ limit: number | null;
3116
+ used: number;
3117
+ /** `null` when `limit` is null. */
3118
+ remaining: number | null;
3119
+ /** When `used` resets. */
3120
+ resetsAt: string | null;
3121
+ }
3021
3122
  interface Email {
3123
+ /**
3124
+ * Send an email.
3125
+ *
3126
+ * Two things to know before your first call. **`category` defaults to
3127
+ * `marketing`**, which fans a multi-recipient send out into one message each and
3128
+ * empties `cc`/`bcc` — pass `'transactional'` for receipts, alerts and codes.
3129
+ * And a non-empty `suppressed` in the result is a **success**, not a failure: it
3130
+ * lists people who had unsubscribed and were therefore skipped.
3131
+ *
3132
+ * Delivery is synchronous today: this resolves once the mail has been handed to
3133
+ * the provider, so a large marketing list takes a while. Outcomes (delivered,
3134
+ * bounced, complained) arrive later — read them with
3135
+ * `email.messages({ batchId })`.
3136
+ *
3137
+ * @example
3138
+ * ```ts
3139
+ * // A receipt: one message, cc preserved, no unsubscribe header.
3140
+ * await email.send({
3141
+ * to: 'customer@example.com',
3142
+ * cc: 'billing@your-co.com',
3143
+ * subject: 'Your receipt',
3144
+ * body: '# Thanks!\n\nOrder #1234 is confirmed.',
3145
+ * category: 'transactional',
3146
+ * });
3147
+ *
3148
+ * // A campaign: per-recipient unsubscribe, your own id for joining stats.
3149
+ * const { suppressed, batchId } = await email.send({
3150
+ * to: subscribers,
3151
+ * subject: 'August newsletter',
3152
+ * body: markdown,
3153
+ * batchId: 'newsletter-2026-08',
3154
+ * });
3155
+ * console.log(`skipped ${suppressed.length} unsubscribed`);
3156
+ * const stats = await email.batch(batchId);
3157
+ * ```
3158
+ */
3159
+ send(options: EmailSendOptions): Promise<EmailSendResult>;
3160
+ /**
3161
+ * Your app's sending allowance and how much is left.
3162
+ *
3163
+ * Useful before a large send: check `remaining` and split the list rather than
3164
+ * discovering the limit as a failure partway through. Going over throws with
3165
+ * `outbound_daily_cap_exceeded`.
3166
+ */
3167
+ quota(): Promise<EmailQuota>;
3022
3168
  /** Counts, rates and a timeseries over a window (default: last 24h). */
3023
3169
  stats(options?: EmailWindowOptions & {
3024
3170
  buckets?: number;
@@ -3738,13 +3884,25 @@ declare class MindStudioAgent$1 {
3738
3884
  */
3739
3885
  get analytics(): Analytics;
3740
3886
  /**
3741
- * Outbound email: the per-recipient delivery log, blast stats, and this app's
3742
- * unsubscribe list. Sending is the `sendEmail` action, not this namespace.
3887
+ * Outbound email: sending, the per-recipient delivery log, blast stats, and
3888
+ * this app's unsubscribe list.
3889
+ *
3890
+ * `email.send()` is the send path — the `sendEmail` action still works and runs
3891
+ * the same code, but `send()` returns a receipt including the `batchId` you read
3892
+ * stats back with. Note `category` defaults to `'marketing'`; see
3893
+ * {@link Email.send}.
3743
3894
  *
3744
3895
  * @example
3745
3896
  * ```ts
3746
3897
  * import { email } from '@mindstudio-ai/agent';
3747
3898
  *
3899
+ * await email.send({
3900
+ * to: 'a@b.com',
3901
+ * subject: 'Your receipt',
3902
+ * body: 'Thanks!',
3903
+ * category: 'transactional',
3904
+ * });
3905
+ *
3748
3906
  * // A support lookup: did this person get their mail?
3749
3907
  * const { messages } = await email.messages({ recipient: 'a@b.com' });
3750
3908
  *
@@ -11205,11 +11363,15 @@ declare const voice: Voice;
11205
11363
  */
11206
11364
  declare const analytics: Analytics;
11207
11365
  /**
11208
- * Your app's outbound email — the delivery log, blast stats, and the unsubscribe
11209
- * list. Sending is `mindstudio.sendEmail(...)`; this is everything after it.
11366
+ * Your app's outbound email — sending, the delivery log, blast stats, and the
11367
+ * unsubscribe list.
11368
+ *
11369
+ * `email.send()` is the send path. `mindstudio.sendEmail(...)` still works and
11370
+ * runs the same code underneath, but `send()` returns a proper receipt and sits
11371
+ * next to everything you do with the result.
11210
11372
  *
11211
11373
  * Scoped to the executing app by its request token, so there is no appId to pass
11212
- * and no way to read another app's mail.
11374
+ * and no way to read or send as another app.
11213
11375
  *
11214
11376
  * @example
11215
11377
  * ```ts
package/dist/index.js CHANGED
@@ -3026,6 +3026,12 @@ function createAnalytics(call) {
3026
3026
  var iso = (v) => v === void 0 ? void 0 : v instanceof Date ? v.toISOString() : v;
3027
3027
  function createEmail(call) {
3028
3028
  return {
3029
+ send(options) {
3030
+ return call("send", options);
3031
+ },
3032
+ quota() {
3033
+ return call("quota", {});
3034
+ },
3029
3035
  stats(options) {
3030
3036
  return call("stats", {
3031
3037
  start: iso(options?.start),
@@ -6824,13 +6830,25 @@ var MindStudioAgent = class {
6824
6830
  );
6825
6831
  }
6826
6832
  /**
6827
- * Outbound email: the per-recipient delivery log, blast stats, and this app's
6828
- * unsubscribe list. Sending is the `sendEmail` action, not this namespace.
6833
+ * Outbound email: sending, the per-recipient delivery log, blast stats, and
6834
+ * this app's unsubscribe list.
6835
+ *
6836
+ * `email.send()` is the send path — the `sendEmail` action still works and runs
6837
+ * the same code, but `send()` returns a receipt including the `batchId` you read
6838
+ * stats back with. Note `category` defaults to `'marketing'`; see
6839
+ * {@link Email.send}.
6829
6840
  *
6830
6841
  * @example
6831
6842
  * ```ts
6832
6843
  * import { email } from '@mindstudio-ai/agent';
6833
6844
  *
6845
+ * await email.send({
6846
+ * to: 'a@b.com',
6847
+ * subject: 'Your receipt',
6848
+ * body: 'Thanks!',
6849
+ * category: 'transactional',
6850
+ * });
6851
+ *
6834
6852
  * // A support lookup: did this person get their mail?
6835
6853
  * const { messages } = await email.messages({ recipient: 'a@b.com' });
6836
6854
  *