@mindstudio-ai/agent 0.1.109 → 0.1.111

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/llms.txt CHANGED
@@ -795,6 +795,7 @@ Search the web using the Perplexity API and return structured results.
795
795
 
796
796
  #### sendEmail
797
797
  Send an email to one or more recipient addresses.
798
+ - If you are writing a backend method for a v2 app, prefer mindstudio.email.send({...}) — it takes the same fields, returns the batchId you read stats back with, and sits alongside email.messages / email.batch / email.suppress. This action remains fully supported and runs the same code; it is also the only way to use connectionId or generateHtml.
798
799
  - Use the "to" field to send to one or more specific recipient email addresses directly. Allowed recipients depend on the sender: when the app sends from a domain it owns (a verified custom domain or its <slug>.madewithremy.com subdomain) any recipient is allowed; when it falls back to the shared Remy address, recipients must be verified app users or members of the app's organization. (v1 apps cannot use a direct "to" — they must resolve recipients via a connection.)
799
800
  - Alternatively, recipient email addresses can be resolved from OAuth connections configured by the app creator via connectionId. The user running the workflow does not specify the recipient directly.
800
801
  - Use "cc" and "bcc" to add visible / hidden recipients (a string or an array). They are subject to the same recipient rules as "to".
@@ -815,9 +816,9 @@ Send an email to one or more recipient addresses.
815
816
  - The special connectionId "trigger_email" uses the email address that triggered the workflow.
816
817
  - Sends default to category "marketing": every message carries a one-click unsubscribe header pointing at the app's own domain, and recipients who previously unsubscribed from this app are skipped and returned in "suppressed". Because the unsubscribe link is per-recipient, a marketing send delivers one separate message per recipient and cc/bcc are folded into that list.
817
818
  - Set category to "transactional" for receipts, alerts, password resets and anything a recipient must not be able to opt out of. Transactional sends carry no unsubscribe header, ignore the unsubscribe list, and keep cc/bcc on a single message — use it whenever cc/bcc semantics matter.
818
- - The subject is stored verbatim in the app's delivery log, which every workspace member can read for 90 days. Never put a secret in the subject — no one-time codes, no magic-link tokens, no password-reset tokens. Put those in the body, which is never stored.
819
- - Input: `{ subject: string, body: string, to?: string | string[], cc?: string | string[], bcc?: string | string[], connectionId?: string, generateHtml?: boolean, generateHtmlInstructions?: string, generateHtmlModelOverride?: { model: string, temperature: number, maxResponseTokens: number, ignorePreamble?: boolean, userMessagePreprocessor?: { dataSource?: string, messageTemplate?: string, maxResults?: number, enabled?: boolean, shouldInherit?: boolean }, preamble?: string, multiModelEnabled?: boolean, editResponseEnabled?: boolean, config?: object }, attachments?: (string | { url: string, filename?: string, contentType?: string })[], from?: string, bodyType?: "auto" | "html" | "markdown" | "text", text?: string, replyTo?: string, inReplyTo?: string, references?: string[], category?: "transactional" | "marketing" }`
820
- - Output: `{ recipients: string[], cc: string[], bcc: string[], from: string, suppressed: string[] }`
819
+ - The subject is stored verbatim in the app's delivery log, which every workspace member can read for 90 days. Never put a secret in the subject — no one-time codes, no magic-link tokens, no password-reset tokens. Put those in the body of a "transactional" send: a small transactional send is delivered immediately and its body is never stored. A "marketing" send, or any large send, is queued for delivery, which means its body is held in internal storage until the send finishes — so do not put a secret in the body of one of those either.
820
+ - Input: `{ subject: string, body: string, to?: string | string[], cc?: string | string[], bcc?: string | string[], connectionId?: string, generateHtml?: boolean, generateHtmlInstructions?: string, generateHtmlModelOverride?: { model: string, temperature: number, maxResponseTokens: number, ignorePreamble?: boolean, userMessagePreprocessor?: { dataSource?: string, messageTemplate?: string, maxResults?: number, enabled?: boolean, shouldInherit?: boolean }, preamble?: string, multiModelEnabled?: boolean, editResponseEnabled?: boolean, config?: object }, attachments?: (string | { url: string, filename?: string, contentType?: string })[], from?: string, bodyType?: "auto" | "html" | "markdown" | "text", text?: string, replyTo?: string, inReplyTo?: string, references?: string[], category?: "transactional" | "marketing", batchId?: string }`
821
+ - Output: `{ recipients: string[], cc: string[], bcc: string[], from: string, suppressed: string[], batchId: string }`
821
822
 
822
823
  #### sendGmailDraft
823
824
  Send an existing draft from the connected Gmail account.
@@ -1890,7 +1891,7 @@ const context = results.map((r) => r.text).join(String.fromCharCode(10, 10));
1890
1891
 
1891
1892
  // narrow before ranking: metadata tags, filename, pages, required words
1892
1893
  await Policies.search('termination clause', {
1893
- filter: { metadata: { department: 'legal', year: [2025, 2026] }, phrase: 'notice period' },
1894
+ filter: { metadata: { department: 'legal', signedAt: { gte: 20250101, lte: 20260630 } }, phrase: 'notice period' },
1894
1895
  maxPerDocument: 2, // stop one document monopolizing the results
1895
1896
  });
1896
1897
 
@@ -1911,7 +1912,9 @@ const chunks = await Policies.chunks(docs[0].id); // why a document does o
1911
1912
 
1912
1913
  Also on each hit: `retrievalRank`/`retrievalScore` (position before reranking — compare with the final position to see what reranking did). Three opt-in search options for debugging and display: `explain: true` adds `explain.{dense,lexical,matchedVia}` so you can see which half of hybrid found a hit; `expand: 1` adds `neighbors.{before,after}` for surrounding context; `highlight: true` adds `matches` — `{start, end}` offsets of query terms in `text`, for rendering highlights. None of them changes the results or their order.
1913
1914
 
1914
- `filter` fields (all AND together, and only narrow): `metadata` (per-key equals, or any-of via an array), `filename`, `documentIds`, `pages: {min?, max?}`, `contains` (all words, any order), `phrase` (exact adjacent sequence). Document metadata is set at add time: scalars only, ≤16 keys, keys `[a-zA-Z0-9_-]`. Re-adding the same bytes with different metadata updates the tags in place — no re-processing.
1915
+ Score semantics: `score`'s scale depends on the mode — cosine similarity (`semantic`), a rank-fusion reciprocal (`hybrid`; small numbers, not similarities), keyword-overlap weight (`lexical`) — and when reranking ran, it's the reranker's 0–1 relevance instead (the retrieval value stays in `retrievalScore`). So with reranking on (the default), put quality cutoffs on `score`. `scoreThreshold` cuts on the retrieval branch BEFORE fusion/reranking — a per-embedding-model cosine floor, not a relevance cutoff — so leave it unset unless you've measured it on your corpus.
1916
+
1917
+ `filter` fields (all AND together, and only narrow): `metadata` (per-key equals, any-of via an array, or a numeric range via `{gte?, lte?}`), `filename`, `documentIds`, `pages: {min?, max?}`, `contains` (all words, any order), `phrase` (exact adjacent sequence). Document metadata is set at add time: scalars only, ≤16 keys, keys `[a-zA-Z0-9_-]`. Ranges are numeric only — to filter by date, store dates as sortable integers (`20250315`-style YYYYMMDD, or epoch seconds) and range on those. Re-adding the same bytes with different metadata updates the tags in place — no re-processing.
1915
1918
 
1916
1919
  Search is deterministic for a fixed corpus and configuration — same query, same order — so regression checks are meaningful. `search()` also returns `latencyMs`.
1917
1920
 
@@ -1921,7 +1924,7 @@ Supported: pdf, docx, pptx, xlsx, odt, rtf, epub, images, txt, md, json, csv, ts
1921
1924
 
1922
1925
  Adding the same bytes twice is free — documents are content-addressed, so a re-add is a no-op when this source has already processed those exact bytes under its current configuration. Only reconfiguring the source makes a re-add do work again, and that is an explicit owner-triggered migration, never a side effect of a deploy.
1923
1926
 
1924
- Everything in `SearchOptions` — `mode`, `filter`, `rerank`, `hybrid`, `maxPerDocument`, `highlight` — is free to change and takes effect on the next search. How documents are chunked and embedded is configured on the corpus itself with `mindstudio-prod datasources config` — not in code — and changing it on a populated source is rejected rather than silently rebuilding.
1927
+ Everything in `SearchOptions` — `mode`, `filter`, `rerank`, `hybrid`, `maxPerDocument`, `highlight` — is free to change and takes effect on the next search. How documents are chunked and embedded is configured on the corpus itself with `remy-admin datasources config` — not in code — and changing it on a populated source is rejected rather than silently rebuilding.
1925
1928
 
1926
1929
  **A data source is live and shared.** Unlike database tables there is no dev copy and no per-release isolation: adding or removing a document changes what the deployed app retrieves, immediately. Scenarios never reset a data source, and re-ingesting a large corpus costs real money.
1927
1930
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindstudio-ai/agent",
3
- "version": "0.1.109",
3
+ "version": "0.1.111",
4
4
  "description": "TypeScript SDK for MindStudio direct step execution",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",