@mindstudio-ai/agent 0.1.104 → 0.1.105

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
@@ -813,8 +813,10 @@ Send an email to one or more recipient addresses.
813
813
  - For threaded replies in a shared inbox, set inReplyTo (the Message-ID being replied to) and references (prior Message-IDs in the thread).
814
814
  - connectionId can be a comma-separated list to send to multiple recipients.
815
815
  - The special connectionId "trigger_email" uses the email address that triggered the workflow.
816
- - 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[] }`
817
- - Output: `{ recipients: string[], cc: string[], bcc: string[], from: string }`
816
+ - 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
+ - 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
+ - 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" }`
819
+ - Output: `{ recipients: string[], cc: string[], bcc: string[], from: string, suppressed: string[] }`
818
820
 
819
821
  #### sendGmailDraft
820
822
  Send an existing draft from the connected Gmail account.
@@ -1921,3 +1923,37 @@ Adding the same bytes twice is free — documents are content-addressed, so a re
1921
1923
  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.
1922
1924
 
1923
1925
  **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.
1926
+
1927
+ #### `analytics` — read the app's own traffic + event analytics
1928
+
1929
+ The platform auto-tracks pageviews (and custom events via the frontend's `analytics.track()`); the backend `analytics` namespace is the read side, so app code can correlate real traffic with its own data — lifetime views next to each blog post, "N people reading now", conversions beside the records that produced them. Backend only (hook token); reads the LIVE app's real traffic even from a dev sandbox. Rate limited per app (120 reads/min).
1930
+
1931
+ One general read, `query()`, shaped like the Plausible/GA4 query APIs:
1932
+
1933
+ ```typescript
1934
+ import { analytics } from '@mindstudio-ai/agent';
1935
+
1936
+ // Lifetime pageviews + unique visitors per page — top 10.
1937
+ const top = await analytics.query({
1938
+ metrics: ['pageviews', 'visitors'],
1939
+ dimensions: ['path'],
1940
+ dateRange: 'all',
1941
+ limit: 10,
1942
+ });
1943
+ // top.results[0] → { dimensions: { path: '/post/hello' }, metrics: { pageviews: 4210, visitors: 1830 } }
1944
+
1945
+ // Daily views for one post, full history.
1946
+ const series = await analytics.query({
1947
+ metrics: ['pageviews'],
1948
+ dimensions: ['time'],
1949
+ granularity: 'day',
1950
+ filters: [['is', 'path', ['/post/hello']]],
1951
+ dateRange: 'all',
1952
+ });
1953
+ ```
1954
+
1955
+ Grammar: `metrics` from `pageviews | visitors | visits | events`; `dimensions` is at most ONE entity dimension (`path`, `referrerHost`, `sourceCategory`, `country`, `city`, `deviceType`, `browser`, `os`, `language`, `visitorType`, `utmSource`…`utmContent`, `eventName`) OR `'time'` (with `granularity: '5m'|'hour'|'day'|'week'|'month'` and optional IANA `timezone`); `filters` are `[op, dimension, values]` triples with ops `is | is_not | contains`; `dateRange` is a shorthand (`'1h'|'24h'|'7d'|'30d'|'90d'|'all'`) or `[startISO, endISO]`; `orderBy` (grouped only) accepts `pageviews` or `events`. With `dateRange: 'all'`, granularity is a minimum — the server coarsens as history grows. `city` filter values are plain city names (any country) and always read the 90-day event detail.
1956
+
1957
+ **Retention split — the one thing to get right:** queries whose filters are all `is` and touch at most one dimension read a rollup kept forever (full lifetime history, exact unique visitors). Cross-dimension intersections, `is_not`, and `contains` scan raw events retained for 90 days; the server clamps the window and reports it. Check `meta`: `source` (`rollup` vs `events`), `clamped`, `window.served`, and `metricsOmitted` — metrics a shape can't carry (e.g. `visits` on grouped reads) are omitted there, never returned as silent zeros. `meta.total` carries the unpaginated group count for paging.
1958
+
1959
+ Specials (same `dateRange`/filter-triple grammar): `analytics.live()` → `{count, countries, sparkline}` right now; `analytics.sources(opts?)` → per-session first-source ranking (UTM > referrer > direct) classified by category/vendor incl. AI assistants; `analytics.map(opts?)` → city lat/lon points; `analytics.aiSources(opts?)` → AI-assistant referrals per vendor; `analytics.crawlers.overview()/timeseries()/recent()` → bot/AI-crawler ingestion of the app's pages.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindstudio-ai/agent",
3
- "version": "0.1.104",
3
+ "version": "0.1.105",
4
4
  "description": "TypeScript SDK for MindStudio direct step execution",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",