flowstack-sdk 0.2.1 → 0.2.2

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
@@ -1553,6 +1553,83 @@ Return value:
1553
1553
 
1554
1554
  ---
1555
1555
 
1556
+ ## Private Messaging (DMs)
1557
+
1558
+ Built-app users can exchange private, one-to-one messages. The DM store is **server-owned and ACL'd**: the backend pins `from` to the caller's JWT identity, only ever returns threads the caller participates in, and gates sends on a **mutually-consented (open) thread** — neither party ever learns the other's contact details.
1559
+
1560
+ Private messaging is a **built-app capability**. It requires an `appScope` on the `FlowstackProvider` config; in a Casino personal session the backend returns 403. All symbols below ship in **0.2.2+**.
1561
+
1562
+ > **Security:** message bodies are UNTRUSTED user input. Render them as plain text or sanitized markdown — never as raw HTML (no `dangerouslySetInnerHTML`). If a body is ever passed to an agent, treat it as data, not instructions.
1563
+
1564
+ ### useThreads — list a user's threads
1565
+
1566
+ ```tsx
1567
+ import { useThreads } from 'flowstack-sdk';
1568
+
1569
+ const { threads, isLoading, error, refresh, openThread } = useThreads({
1570
+ refreshInterval: 5000, // optional auto-poll (ms); off by default
1571
+ });
1572
+
1573
+ // Each thread: { pair_key, with_user_key, status: 'pending' | 'open', last_message, unread_count, updated_at }
1574
+ threads.map((t) => <ThreadRow key={t.pair_key} counterpart={t.with_user_key} unread={t.unread_count} />);
1575
+
1576
+ // Consent to open a thread — becomes sendable only once BOTH parties consent.
1577
+ const status = await openThread(otherUserKey); // 'pending' | 'open' | null
1578
+ ```
1579
+
1580
+ ### useMessages — read + send within one thread
1581
+
1582
+ ```tsx
1583
+ import { useMessages } from 'flowstack-sdk';
1584
+
1585
+ const { messages, send, isLoading, error, refresh } = useMessages(counterpartUserKey, {
1586
+ limit: 50, // default 50, max 200
1587
+ refreshInterval: 4000,
1588
+ });
1589
+
1590
+ await send('hey there'); // 403 / error if the thread is not yet mutually open
1591
+ messages.map((m) => <Bubble key={m.message_id} mine={m.from === myKey}>{m.body}</Bubble>);
1592
+ ```
1593
+
1594
+ ### Client functions (non-React)
1595
+
1596
+ All take `(credentials, …, config)` where `config` must carry `appScope`. Each returns an `ApiResponse<T>` (`{ ok, data, error }`), except `dmPairKey` which is a pure helper.
1597
+
1598
+ ```ts
1599
+ import {
1600
+ listThreads, // (creds, config) → { threads: DmThread[]; count }
1601
+ listMessages, // (creds, withUserKey, { limit?, before? }, config) → { messages: DmMessage[]; count }
1602
+ sendMessage, // (creds, toUserKey, body, config) → { message_id, created_at } — 403 unless thread open
1603
+ openThread, // (creds, withUserKey, config) → { pair_key, status } — record caller's consent
1604
+ markMessageRead, // (creds, messageId, config) → { message_id, read } — recipient only
1605
+ dmPairKey, // (a, b) → string — deterministic, order-independent thread key (sorted, '::'-joined)
1606
+ } from 'flowstack-sdk';
1607
+ ```
1608
+
1609
+ **Types:**
1610
+
1611
+ ```ts
1612
+ interface DmMessage {
1613
+ message_id: string;
1614
+ from: string;
1615
+ to: string;
1616
+ body: string; // UNTRUSTED — render as text, never raw HTML
1617
+ created_at: string;
1618
+ read_at: string | null;
1619
+ }
1620
+
1621
+ interface DmThread {
1622
+ pair_key: string;
1623
+ with_user_key: string;
1624
+ status: 'pending' | 'open';
1625
+ last_message: DmMessage | null;
1626
+ unread_count: number;
1627
+ updated_at: string | null;
1628
+ }
1629
+ ```
1630
+
1631
+ ---
1632
+
1556
1633
  ## Components
1557
1634
 
1558
1635
  ### Pre-built Page Components
@@ -1 +1 @@
1
- export { bM as CACHE_TTL, c7 as CreateSiteParams, N as FlowstackClientConfig, c8 as RedisConfig, bL as RequestOptions, bD as addPiiAllowlistTerm, bk as addSiteFile, be as checkAdminPermissions, aZ as createDataSource, bj as createSite, aN as createWorkspace, c4 as deleteCached, a$ as deleteDataSource, aS as deleteDataset, bv as deleteDocuments, bm as deleteSite, bp as deleteSiteVersion, b9 as deleteUser, bJ as deleteUserCollection, b0 as executeQuery, b1 as executeQueryWithConfig, bK as exportUserCollection, aL as flowstackFetch, c2 as getCached, bQ as getCachedDatasets, bW as getCachedReports, b$ as getCachedSites, bT as getCachedVisualizations, bN as getCachedWorkspaces, bf as getConversationHistory, aQ as getDataset, aR as getDatasetPreview, aX as getModel, bC as getPiiAllowlist, bz as getPiiSettings, bi as getSite, bn as getSiteVersions, b7 as getUser, bc as getUserActivity, bH as getUserCollectionDocuments, bI as getUserCollectionSchema, bG as getUserCollections, bF as getUserDataOverview, bd as getUserStats, aO as getWorkspace, b5 as googleLogin, by as importFromGitHub, bt as insertDocuments, b_ as invalidateAllUserCache, bS as invalidateDatasetsCache, bY as invalidateReportsCache, c1 as invalidateSitesCache, bV as invalidateVisualizationsCache, bZ as invalidateWorkspaceArtifacts, bP as invalidateWorkspacesCache, bw as invokeTool, bg as listAgents, aY as listDataSources, aP as listDatasets, bx as listGitHubRepos, aV as listModels, aU as listReports, aW as listScripts, bh as listSites, b6 as listUsers, aT as listVisualizations, aM as listWorkspaces, b3 as login, bB as previewPiiMasking, bo as promoteSiteVersion, bl as publishStagedSite, bs as publishToGitHub, c5 as queryCollection, bb as reactivateUser, b4 as register, bE as removePiiAllowlistTerm, br as removeSiteAlias, c3 as setCached, bR as setCachedDatasets, bX as setCachedReports, c0 as setCachedSites, bU as setCachedVisualizations, bO as setCachedWorkspaces, bq as setSiteAlias, ba as suspendUser, a_ as testDataSource, bu as updateDocuments, bA as updatePiiSettings, b8 as updateUser, c6 as uploadDocument, b2 as uploadFile } from '../index-BkACA2ls.mjs';
1
+ export { bU as CACHE_TTL, cf as CreateSiteParams, o as DmMessage, D as DmThread, R as FlowstackClientConfig, cg as RedisConfig, bT as RequestOptions, bL as addPiiAllowlistTerm, bm as addSiteFile, bg as checkAdminPermissions, a$ as createDataSource, bl as createSite, aP as createWorkspace, cc as deleteCached, b1 as deleteDataSource, aU as deleteDataset, bx as deleteDocuments, bo as deleteSite, br as deleteSiteVersion, bb as deleteUser, bR as deleteUserCollection, bD as dmPairKey, b2 as executeQuery, b3 as executeQueryWithConfig, bS as exportUserCollection, aN as flowstackFetch, ca as getCached, bY as getCachedDatasets, c2 as getCachedReports, c7 as getCachedSites, b$ as getCachedVisualizations, bV as getCachedWorkspaces, bh as getConversationHistory, aS as getDataset, aT as getDatasetPreview, aZ as getModel, bK as getPiiAllowlist, bH as getPiiSettings, bk as getSite, bp as getSiteVersions, b9 as getUser, be as getUserActivity, bP as getUserCollectionDocuments, bQ as getUserCollectionSchema, bO as getUserCollections, bN as getUserDataOverview, bf as getUserStats, aQ as getWorkspace, b7 as googleLogin, bG as importFromGitHub, bv as insertDocuments, c6 as invalidateAllUserCache, b_ as invalidateDatasetsCache, c4 as invalidateReportsCache, c9 as invalidateSitesCache, c1 as invalidateVisualizationsCache, c5 as invalidateWorkspaceArtifacts, bX as invalidateWorkspacesCache, bE as invokeTool, bi as listAgents, a_ as listDataSources, aR as listDatasets, bF as listGitHubRepos, bz as listMessages, aX as listModels, aW as listReports, aY as listScripts, bj as listSites, by as listThreads, b8 as listUsers, aV as listVisualizations, aO as listWorkspaces, b5 as login, bC as markMessageRead, bB as openThread, bJ as previewPiiMasking, bq as promoteSiteVersion, bn as publishStagedSite, bu as publishToGitHub, cd as queryCollection, bd as reactivateUser, b6 as register, bM as removePiiAllowlistTerm, bt as removeSiteAlias, bA as sendMessage, cb as setCached, bZ as setCachedDatasets, c3 as setCachedReports, c8 as setCachedSites, c0 as setCachedVisualizations, bW as setCachedWorkspaces, bs as setSiteAlias, bc as suspendUser, b0 as testDataSource, bw as updateDocuments, bI as updatePiiSettings, ba as updateUser, ce as uploadDocument, b4 as uploadFile } from '../index-CUyJ5c2d.mjs';
@@ -1 +1 @@
1
- export { bM as CACHE_TTL, c7 as CreateSiteParams, N as FlowstackClientConfig, c8 as RedisConfig, bL as RequestOptions, bD as addPiiAllowlistTerm, bk as addSiteFile, be as checkAdminPermissions, aZ as createDataSource, bj as createSite, aN as createWorkspace, c4 as deleteCached, a$ as deleteDataSource, aS as deleteDataset, bv as deleteDocuments, bm as deleteSite, bp as deleteSiteVersion, b9 as deleteUser, bJ as deleteUserCollection, b0 as executeQuery, b1 as executeQueryWithConfig, bK as exportUserCollection, aL as flowstackFetch, c2 as getCached, bQ as getCachedDatasets, bW as getCachedReports, b$ as getCachedSites, bT as getCachedVisualizations, bN as getCachedWorkspaces, bf as getConversationHistory, aQ as getDataset, aR as getDatasetPreview, aX as getModel, bC as getPiiAllowlist, bz as getPiiSettings, bi as getSite, bn as getSiteVersions, b7 as getUser, bc as getUserActivity, bH as getUserCollectionDocuments, bI as getUserCollectionSchema, bG as getUserCollections, bF as getUserDataOverview, bd as getUserStats, aO as getWorkspace, b5 as googleLogin, by as importFromGitHub, bt as insertDocuments, b_ as invalidateAllUserCache, bS as invalidateDatasetsCache, bY as invalidateReportsCache, c1 as invalidateSitesCache, bV as invalidateVisualizationsCache, bZ as invalidateWorkspaceArtifacts, bP as invalidateWorkspacesCache, bw as invokeTool, bg as listAgents, aY as listDataSources, aP as listDatasets, bx as listGitHubRepos, aV as listModels, aU as listReports, aW as listScripts, bh as listSites, b6 as listUsers, aT as listVisualizations, aM as listWorkspaces, b3 as login, bB as previewPiiMasking, bo as promoteSiteVersion, bl as publishStagedSite, bs as publishToGitHub, c5 as queryCollection, bb as reactivateUser, b4 as register, bE as removePiiAllowlistTerm, br as removeSiteAlias, c3 as setCached, bR as setCachedDatasets, bX as setCachedReports, c0 as setCachedSites, bU as setCachedVisualizations, bO as setCachedWorkspaces, bq as setSiteAlias, ba as suspendUser, a_ as testDataSource, bu as updateDocuments, bA as updatePiiSettings, b8 as updateUser, c6 as uploadDocument, b2 as uploadFile } from '../index-BkACA2ls.js';
1
+ export { bU as CACHE_TTL, cf as CreateSiteParams, o as DmMessage, D as DmThread, R as FlowstackClientConfig, cg as RedisConfig, bT as RequestOptions, bL as addPiiAllowlistTerm, bm as addSiteFile, bg as checkAdminPermissions, a$ as createDataSource, bl as createSite, aP as createWorkspace, cc as deleteCached, b1 as deleteDataSource, aU as deleteDataset, bx as deleteDocuments, bo as deleteSite, br as deleteSiteVersion, bb as deleteUser, bR as deleteUserCollection, bD as dmPairKey, b2 as executeQuery, b3 as executeQueryWithConfig, bS as exportUserCollection, aN as flowstackFetch, ca as getCached, bY as getCachedDatasets, c2 as getCachedReports, c7 as getCachedSites, b$ as getCachedVisualizations, bV as getCachedWorkspaces, bh as getConversationHistory, aS as getDataset, aT as getDatasetPreview, aZ as getModel, bK as getPiiAllowlist, bH as getPiiSettings, bk as getSite, bp as getSiteVersions, b9 as getUser, be as getUserActivity, bP as getUserCollectionDocuments, bQ as getUserCollectionSchema, bO as getUserCollections, bN as getUserDataOverview, bf as getUserStats, aQ as getWorkspace, b7 as googleLogin, bG as importFromGitHub, bv as insertDocuments, c6 as invalidateAllUserCache, b_ as invalidateDatasetsCache, c4 as invalidateReportsCache, c9 as invalidateSitesCache, c1 as invalidateVisualizationsCache, c5 as invalidateWorkspaceArtifacts, bX as invalidateWorkspacesCache, bE as invokeTool, bi as listAgents, a_ as listDataSources, aR as listDatasets, bF as listGitHubRepos, bz as listMessages, aX as listModels, aW as listReports, aY as listScripts, bj as listSites, by as listThreads, b8 as listUsers, aV as listVisualizations, aO as listWorkspaces, b5 as login, bC as markMessageRead, bB as openThread, bJ as previewPiiMasking, bq as promoteSiteVersion, bn as publishStagedSite, bu as publishToGitHub, cd as queryCollection, bd as reactivateUser, b6 as register, bM as removePiiAllowlistTerm, bt as removeSiteAlias, bA as sendMessage, cb as setCached, bZ as setCachedDatasets, c3 as setCachedReports, c8 as setCachedSites, c0 as setCachedVisualizations, bW as setCachedWorkspaces, bs as setSiteAlias, bc as suspendUser, b0 as testDataSource, bw as updateDocuments, bI as updatePiiSettings, ba as updateUser, ce as uploadDocument, b4 as uploadFile } from '../index-CUyJ5c2d.js';
package/dist/api/index.js CHANGED
@@ -332,6 +332,63 @@ async function deleteDocuments(credentials, collection, filter, config, layer) {
332
332
  config
333
333
  );
334
334
  }
335
+ function dmPairKey(a, b) {
336
+ return [a, b].sort().join("::");
337
+ }
338
+ function requireAppScope(config) {
339
+ const scope = config?.appScope;
340
+ if (!scope) {
341
+ throw new Error("Private messaging requires an app scope (built-app context).");
342
+ }
343
+ return scope;
344
+ }
345
+ async function listThreads(credentials, config) {
346
+ const scope = requireAppScope(config);
347
+ return flowstackFetch(
348
+ `/apps/${encodeURIComponent(scope)}/threads`,
349
+ { credentials },
350
+ config
351
+ );
352
+ }
353
+ async function listMessages(credentials, withUserKey, options, config) {
354
+ const scope = requireAppScope(config);
355
+ const params = new URLSearchParams();
356
+ params.set("with", withUserKey);
357
+ if (options?.limit) params.set("limit", String(options.limit));
358
+ if (options?.before) params.set("before", options.before);
359
+ return flowstackFetch(
360
+ `/apps/${encodeURIComponent(scope)}/messages?${params.toString()}`,
361
+ { credentials },
362
+ config
363
+ );
364
+ }
365
+ async function sendMessage(credentials, toUserKey, body, config) {
366
+ const scope = requireAppScope(config);
367
+ return flowstackFetch(
368
+ `/apps/${encodeURIComponent(scope)}/messages`,
369
+ { method: "POST", credentials, body: { to_user_key: toUserKey, body } },
370
+ config
371
+ );
372
+ }
373
+ async function openThread(credentials, withUserKey, config) {
374
+ const scope = requireAppScope(config);
375
+ const me = credentials.userId;
376
+ if (!me) throw new Error("openThread requires an authenticated user.");
377
+ const pk = dmPairKey(me, withUserKey);
378
+ return flowstackFetch(
379
+ `/apps/${encodeURIComponent(scope)}/threads/${encodeURIComponent(pk)}/consent`,
380
+ { method: "POST", credentials },
381
+ config
382
+ );
383
+ }
384
+ async function markMessageRead(credentials, messageId, config) {
385
+ const scope = requireAppScope(config);
386
+ return flowstackFetch(
387
+ `/apps/${encodeURIComponent(scope)}/messages/${encodeURIComponent(messageId)}/read`,
388
+ { method: "POST", credentials },
389
+ config
390
+ );
391
+ }
335
392
  async function invokeTool(credentials, agentName, toolName, kwargs = {}, config) {
336
393
  return flowstackFetch(
337
394
  "/tool/invoke",
@@ -989,6 +1046,7 @@ exports.deleteSite = deleteSite;
989
1046
  exports.deleteSiteVersion = deleteSiteVersion;
990
1047
  exports.deleteUser = deleteUser;
991
1048
  exports.deleteUserCollection = deleteUserCollection;
1049
+ exports.dmPairKey = dmPairKey;
992
1050
  exports.executeQuery = executeQuery;
993
1051
  exports.executeQueryWithConfig = executeQueryWithConfig;
994
1052
  exports.exportUserCollection = exportUserCollection;
@@ -1030,14 +1088,18 @@ exports.listAgents = listAgents;
1030
1088
  exports.listDataSources = listDataSources;
1031
1089
  exports.listDatasets = listDatasets;
1032
1090
  exports.listGitHubRepos = listGitHubRepos;
1091
+ exports.listMessages = listMessages;
1033
1092
  exports.listModels = listModels;
1034
1093
  exports.listReports = listReports;
1035
1094
  exports.listScripts = listScripts;
1036
1095
  exports.listSites = listSites;
1096
+ exports.listThreads = listThreads;
1037
1097
  exports.listUsers = listUsers;
1038
1098
  exports.listVisualizations = listVisualizations;
1039
1099
  exports.listWorkspaces = listWorkspaces;
1040
1100
  exports.login = login;
1101
+ exports.markMessageRead = markMessageRead;
1102
+ exports.openThread = openThread;
1041
1103
  exports.previewPiiMasking = previewPiiMasking;
1042
1104
  exports.promoteSiteVersion = promoteSiteVersion;
1043
1105
  exports.publishStagedSite = publishStagedSite;
@@ -1047,6 +1109,7 @@ exports.reactivateUser = reactivateUser;
1047
1109
  exports.register = register;
1048
1110
  exports.removePiiAllowlistTerm = removePiiAllowlistTerm;
1049
1111
  exports.removeSiteAlias = removeSiteAlias;
1112
+ exports.sendMessage = sendMessage;
1050
1113
  exports.setCached = setCached;
1051
1114
  exports.setCachedDatasets = setCachedDatasets;
1052
1115
  exports.setCachedReports = setCachedReports;