@adminide-stack/yantra-mobile 12.0.53-alpha.0 → 12.0.53-alpha.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.
Files changed (29) hide show
  1. package/lib/components/KeyboardComposerDock.js +41 -5
  2. package/lib/components/KeyboardComposerDock.js.map +1 -1
  3. package/lib/features/attachments/ComposerAttachMenu.js +189 -0
  4. package/lib/features/attachments/ComposerAttachMenu.js.map +1 -0
  5. package/lib/features/attachments/useImageAttachments.js +23 -15
  6. package/lib/features/attachments/useImageAttachments.js.map +1 -1
  7. package/lib/features/canvas/canvasBoardsSnapshot.js +37 -0
  8. package/lib/features/canvas/canvasBoardsSnapshot.js.map +1 -0
  9. package/lib/features/canvas/nativeViewerRegistry.js +9 -1
  10. package/lib/features/canvas/nativeViewerRegistry.js.map +1 -1
  11. package/lib/features/chat/chatHistorySnapshot.js +103 -0
  12. package/lib/features/chat/chatHistorySnapshot.js.map +1 -0
  13. package/lib/graphql/typePolicies.js +139 -0
  14. package/lib/graphql/typePolicies.js.map +1 -0
  15. package/lib/hooks/useChatApi.js +8 -1
  16. package/lib/hooks/useChatApi.js.map +1 -1
  17. package/lib/index.js +1 -1
  18. package/lib/index.js.map +1 -1
  19. package/lib/module.js +5 -2
  20. package/lib/module.js.map +1 -1
  21. package/lib/screens/Chat/index.js +7 -35
  22. package/lib/screens/Chat/index.js.map +1 -1
  23. package/lib/screens/Home/HomeScreen.js +18 -31
  24. package/lib/screens/Home/HomeScreen.js.map +1 -1
  25. package/lib/screens/Home/components/CanvasPrewarm.js +3 -2
  26. package/lib/screens/Home/components/CanvasPrewarm.js.map +1 -1
  27. package/lib/screens/Home/components/ChatHistoryLanding.js +44 -8
  28. package/lib/screens/Home/components/ChatHistoryLanding.js.map +1 -1
  29. package/package.json +4 -4
@@ -0,0 +1,103 @@
1
+ import AsyncStorage from'@react-native-async-storage/async-storage';const SNAPSHOT_KEY = "yantra.chat-history.snapshot.v1";
2
+ const SNAPSHOT_LIMIT = 10;
3
+ let memory = null;
4
+ let lastWritten = "";
5
+ let hydratePromise = null;
6
+ const listeners = /* @__PURE__ */ new Set();
7
+ function toSession(row) {
8
+ if (!(row == null ? void 0 : row.channelId)) return null;
9
+ const updatedAt = new Date(row.updatedAt);
10
+ const createdAt = new Date(row.createdAt);
11
+ if (Number.isNaN(updatedAt.getTime()) || Number.isNaN(createdAt.getTime())) return null;
12
+ return {
13
+ channelId: row.channelId,
14
+ title: row.title || "New chat",
15
+ preview: row.preview || "",
16
+ mode: row.mode === "deep-search" || row.mode === "build" ? row.mode : "chat",
17
+ updatedAt,
18
+ createdAt,
19
+ isPlaceholder: Boolean(row.isPlaceholder),
20
+ isAttachment: row.isAttachment
21
+ };
22
+ }
23
+ function serializeChatHistorySnapshot(orgName, sessions) {
24
+ const payload = {
25
+ orgName,
26
+ rows: sessions.slice(0, SNAPSHOT_LIMIT).map((row) => ({
27
+ channelId: row.channelId,
28
+ title: row.title,
29
+ preview: row.preview,
30
+ mode: row.mode,
31
+ updatedAt: row.updatedAt.toISOString(),
32
+ createdAt: row.createdAt.toISOString(),
33
+ isPlaceholder: row.isPlaceholder,
34
+ isAttachment: row.isAttachment
35
+ }))
36
+ };
37
+ return JSON.stringify(payload);
38
+ }
39
+ function parseChatHistorySnapshot(raw) {
40
+ if (!raw) return null;
41
+ try {
42
+ const parsed = JSON.parse(raw);
43
+ if (!(parsed == null ? void 0 : parsed.orgName) || !Array.isArray(parsed.rows)) return null;
44
+ const rows = parsed.rows.map(toSession).filter((row) => row !== null);
45
+ if (rows.length === 0) return {
46
+ orgName: parsed.orgName,
47
+ rows: []
48
+ };
49
+ return {
50
+ orgName: parsed.orgName,
51
+ rows
52
+ };
53
+ } catch (e) {
54
+ return null;
55
+ }
56
+ }
57
+ function notify() {
58
+ for (const listener of listeners) listener(memory);
59
+ }
60
+ function peekChatHistorySnapshot(orgName) {
61
+ var _a;
62
+ if (!((_a = memory == null ? void 0 : memory.rows) == null ? void 0 : _a.length)) return [];
63
+ if (orgName && memory.orgName && memory.orgName !== orgName) return [];
64
+ return memory.rows;
65
+ }
66
+ function peekChatHistorySnapshotOrgName() {
67
+ var _a;
68
+ return (_a = memory == null ? void 0 : memory.orgName) != null ? _a : null;
69
+ }
70
+ function subscribeChatHistorySnapshot(listener) {
71
+ listeners.add(listener);
72
+ return () => {
73
+ listeners.delete(listener);
74
+ };
75
+ }
76
+ function persistChatHistorySnapshot(orgName, sessions) {
77
+ const trimmed = typeof orgName === "string" ? orgName.trim() : "";
78
+ if (!trimmed) return;
79
+ const raw = serializeChatHistorySnapshot(trimmed, sessions);
80
+ if (raw === lastWritten) return;
81
+ lastWritten = raw;
82
+ memory = {
83
+ orgName: trimmed,
84
+ rows: sessions.slice(0, SNAPSHOT_LIMIT)
85
+ };
86
+ notify();
87
+ void AsyncStorage.setItem(SNAPSHOT_KEY, raw).catch(() => {
88
+ });
89
+ }
90
+ function hydrateChatHistorySnapshot() {
91
+ if (!hydratePromise) {
92
+ hydratePromise = AsyncStorage.getItem(SNAPSHOT_KEY).then((raw) => {
93
+ const parsed = parseChatHistorySnapshot(raw);
94
+ if (parsed) {
95
+ memory = parsed;
96
+ lastWritten = raw != null ? raw : lastWritten;
97
+ notify();
98
+ }
99
+ return parsed;
100
+ }).catch(() => null);
101
+ }
102
+ return hydratePromise;
103
+ }export{hydrateChatHistorySnapshot,parseChatHistorySnapshot,peekChatHistorySnapshot,peekChatHistorySnapshotOrgName,persistChatHistorySnapshot,serializeChatHistorySnapshot,subscribeChatHistorySnapshot};//# sourceMappingURL=chatHistorySnapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chatHistorySnapshot.js","sources":["../../../src/features/chat/chatHistorySnapshot.ts"],"sourcesContent":["import AsyncStorage from '@react-native-async-storage/async-storage';\nimport type { ChatHistoryMode, ChatHistorySession } from '../../hooks/useChatApi';\n\nconst SNAPSHOT_KEY = 'yantra.chat-history.snapshot.v1';\nconst SNAPSHOT_LIMIT = 10;\n\ntype StoredSession = {\n channelId: string;\n title: string;\n preview: string;\n mode: ChatHistoryMode;\n updatedAt: string;\n createdAt: string;\n isPlaceholder: boolean;\n isAttachment?: boolean;\n};\n\ntype StoredSnapshot = {\n orgName: string;\n rows: StoredSession[];\n};\n\nexport type ChatHistorySnapshot = {\n orgName: string;\n rows: ChatHistorySession[];\n};\n\nlet memory: ChatHistorySnapshot | null = null;\nlet lastWritten = '';\nlet hydratePromise: Promise<ChatHistorySnapshot | null> | null = null;\nconst listeners = new Set<(snap: ChatHistorySnapshot | null) => void>();\n\nfunction toSession(row: StoredSession): ChatHistorySession | null {\n if (!row?.channelId) return null;\n const updatedAt = new Date(row.updatedAt);\n const createdAt = new Date(row.createdAt);\n if (Number.isNaN(updatedAt.getTime()) || Number.isNaN(createdAt.getTime())) return null;\n return {\n channelId: row.channelId,\n title: row.title || 'New chat',\n preview: row.preview || '',\n mode: row.mode === 'deep-search' || row.mode === 'build' ? row.mode : 'chat',\n updatedAt,\n createdAt,\n isPlaceholder: Boolean(row.isPlaceholder),\n isAttachment: row.isAttachment,\n };\n}\n\nexport function serializeChatHistorySnapshot(orgName: string, sessions: ChatHistorySession[]): string {\n const payload: StoredSnapshot = {\n orgName,\n rows: sessions.slice(0, SNAPSHOT_LIMIT).map((row) => ({\n channelId: row.channelId,\n title: row.title,\n preview: row.preview,\n mode: row.mode,\n updatedAt: row.updatedAt.toISOString(),\n createdAt: row.createdAt.toISOString(),\n isPlaceholder: row.isPlaceholder,\n isAttachment: row.isAttachment,\n })),\n };\n return JSON.stringify(payload);\n}\n\nexport function parseChatHistorySnapshot(raw: string | null | undefined): ChatHistorySnapshot | null {\n if (!raw) return null;\n try {\n const parsed = JSON.parse(raw) as StoredSnapshot;\n if (!parsed?.orgName || !Array.isArray(parsed.rows)) return null;\n const rows = parsed.rows.map(toSession).filter((row): row is ChatHistorySession => row !== null);\n if (rows.length === 0) return { orgName: parsed.orgName, rows: [] };\n return { orgName: parsed.orgName, rows };\n } catch {\n return null;\n }\n}\n\nfunction notify() {\n for (const listener of listeners) listener(memory);\n}\n\nexport function peekChatHistorySnapshot(orgName?: string | null): ChatHistorySession[] {\n if (!memory?.rows?.length) return [];\n if (orgName && memory.orgName && memory.orgName !== orgName) return [];\n return memory.rows;\n}\n\nexport function peekChatHistorySnapshotOrgName(): string | null {\n return memory?.orgName ?? null;\n}\n\nexport function subscribeChatHistorySnapshot(listener: (snap: ChatHistorySnapshot | null) => void): () => void {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n}\n\nexport function persistChatHistorySnapshot(orgName: string, sessions: ChatHistorySession[]): void {\n const trimmed = typeof orgName === 'string' ? orgName.trim() : '';\n if (!trimmed) return;\n const raw = serializeChatHistorySnapshot(trimmed, sessions);\n if (raw === lastWritten) return;\n lastWritten = raw;\n memory = { orgName: trimmed, rows: sessions.slice(0, SNAPSHOT_LIMIT) };\n notify();\n void AsyncStorage.setItem(SNAPSHOT_KEY, raw).catch(() => {\n /* disk write is best-effort */\n });\n}\n\nexport function hydrateChatHistorySnapshot(): Promise<ChatHistorySnapshot | null> {\n if (!hydratePromise) {\n hydratePromise = AsyncStorage.getItem(SNAPSHOT_KEY)\n .then((raw) => {\n const parsed = parseChatHistorySnapshot(raw);\n if (parsed) {\n memory = parsed;\n lastWritten = raw ?? lastWritten;\n notify();\n }\n return parsed;\n })\n .catch(() => null);\n }\n return hydratePromise;\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,139 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ function mergeConnectionEdges(existing, incoming, {
21
+ readField
22
+ }) {
23
+ var _a, _b;
24
+ if (!existing) return incoming;
25
+ const existingEdges = (_a = existing.edges) != null ? _a : [];
26
+ const incomingEdges = (_b = incoming.edges) != null ? _b : [];
27
+ const seenIds = /* @__PURE__ */ new Set();
28
+ const merged = [...incomingEdges];
29
+ incomingEdges.forEach((edge) => {
30
+ const node = readField("node", edge);
31
+ const id = node ? readField("id", node) : void 0;
32
+ if (id) seenIds.add(id);
33
+ });
34
+ existingEdges.forEach((edge) => {
35
+ const node = readField("node", edge);
36
+ const id = node ? readField("id", node) : void 0;
37
+ if (id && !seenIds.has(id)) {
38
+ merged.push(edge);
39
+ }
40
+ });
41
+ return __spreadProps(__spreadValues({}, incoming), {
42
+ edges: merged
43
+ });
44
+ }
45
+ function mergeNewsArticlesList(existing, incoming, {
46
+ args
47
+ }) {
48
+ var _a, _b, _c;
49
+ const skip = (_b = (_a = args == null ? void 0 : args.filter) == null ? void 0 : _a.skip) != null ? _b : 0;
50
+ const mergedData = (existing == null ? void 0 : existing.data) ? existing.data.slice(0) : [];
51
+ const incomingData = (_c = incoming == null ? void 0 : incoming.data) != null ? _c : [];
52
+ incomingData.forEach((item, index) => {
53
+ mergedData[skip + index] = item;
54
+ });
55
+ return __spreadProps(__spreadValues({}, incoming), {
56
+ data: mergedData
57
+ });
58
+ }
59
+ function mergeChannelsByUser(existing, incoming, {
60
+ args
61
+ }) {
62
+ var _a;
63
+ const skip = (_a = args == null ? void 0 : args.skip) != null ? _a : 0;
64
+ if (skip === 0) return incoming != null ? incoming : [];
65
+ const merged = existing ? existing.slice(0) : [];
66
+ (incoming != null ? incoming : []).forEach((channel, index) => {
67
+ merged[skip + index] = channel;
68
+ });
69
+ return merged;
70
+ }
71
+ function mergeMessagesConnection(existing, incoming, {
72
+ args
73
+ }) {
74
+ var _a, _b;
75
+ if (!incoming) return existing;
76
+ const skip = (_a = args == null ? void 0 : args.skip) != null ? _a : 0;
77
+ if (skip === 0 || !existing) return incoming;
78
+ const mergedData = (existing == null ? void 0 : existing.data) ? existing.data.slice(0) : [];
79
+ const incomingData = (_b = incoming == null ? void 0 : incoming.data) != null ? _b : [];
80
+ incomingData.forEach((item, index) => {
81
+ mergedData[skip + index] = item;
82
+ });
83
+ return __spreadProps(__spreadValues({}, incoming), {
84
+ data: mergedData
85
+ });
86
+ }
87
+ const typePolicies = {
88
+ Query: {
89
+ fields: {
90
+ // Chat sessions: ignore pagination args so cache stores one canonical list per archive filter
91
+ getAccountChatSessions: {
92
+ keyArgs: ["includeArchived"],
93
+ merge: mergeConnectionEdges
94
+ },
95
+ // Chat messages (account API): keyed by sessionId, ignore pagination args
96
+ getAccountChatMessages: {
97
+ keyArgs: ["sessionId"],
98
+ merge: mergeConnectionEdges
99
+ },
100
+ getAccountNewsArticles: {
101
+ keyArgs: ["filter", ["topic"]],
102
+ merge: mergeNewsArticlesList
103
+ },
104
+ // Chat-history channels: one canonical list per (role, criteria)
105
+ // — criteria carries { type, orgName }. Ignore limit/skip/sort so
106
+ // cache-first serves the same list across navigations and loadMore
107
+ // appends instead of replacing.
108
+ channelsByUser: {
109
+ keyArgs: ["role", "criteria"],
110
+ merge: mergeChannelsByUser
111
+ },
112
+ // History titles (`editedBy` + type) and thread details (`channelId`)
113
+ // must not share a cache slot. Drop skip/limit so pages merge.
114
+ messages: {
115
+ keyArgs: ["channelId", "editedBy", "type", "props", "sort", "parentId"],
116
+ merge: mergeMessagesConnection
117
+ }
118
+ }
119
+ },
120
+ // `MessengerUser` selects `fullName @client`. With no local resolver the cache
121
+ // cannot satisfy that field, so every UserAccount read is "incomplete" — which
122
+ // makes cache-first treat channelsByUser / messages as a miss and refetch on
123
+ // every navigation. Compute fullName locally so the cache reads back complete.
124
+ UserAccount: {
125
+ fields: {
126
+ fullName: {
127
+ read(_existing, {
128
+ readField
129
+ }) {
130
+ var _a, _b;
131
+ const given = (_a = readField("givenName")) != null ? _a : "";
132
+ const family = (_b = readField("familyName")) != null ? _b : "";
133
+ const joined = `${given} ${family}`.replace(/\s+/g, " ").trim();
134
+ return joined || readField("username") || "";
135
+ }
136
+ }
137
+ }
138
+ }
139
+ };export{typePolicies};//# sourceMappingURL=typePolicies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typePolicies.js","sources":["../../src/graphql/typePolicies.ts"],"sourcesContent":["/**\n * Apollo cache field policies — same contract as account/browser.\n *\n * Without these, `cache-first` treats `channelsByUser` / `messages` as a miss\n * (pagination args re-key the list; `fullName @client` has no reader) and the\n * history screen + thread details refetch on every visit.\n */\n\nfunction mergeConnectionEdges(existing: any, incoming: any, { readField }: any) {\n if (!existing) return incoming;\n\n const existingEdges = existing.edges ?? [];\n const incomingEdges = incoming.edges ?? [];\n\n const seenIds = new Set<string>();\n const merged = [...incomingEdges];\n\n incomingEdges.forEach((edge: any) => {\n const node = readField('node', edge);\n const id = node ? readField('id', node) : undefined;\n if (id) seenIds.add(id as string);\n });\n\n existingEdges.forEach((edge: any) => {\n const node = readField('node', edge);\n const id = node ? readField('id', node) : undefined;\n if (id && !seenIds.has(id as string)) {\n merged.push(edge);\n }\n });\n\n return {\n ...incoming,\n edges: merged,\n };\n}\n\nfunction mergeNewsArticlesList(existing: any, incoming: any, { args }: any) {\n const skip = args?.filter?.skip ?? 0;\n const mergedData = existing?.data ? existing.data.slice(0) : [];\n const incomingData = incoming?.data ?? [];\n\n incomingData.forEach((item: any, index: number) => {\n mergedData[skip + index] = item;\n });\n\n return {\n ...incoming,\n data: mergedData,\n };\n}\n\n// Chat-history list: `channelsByUser` returns a flat list of normalized Channel\n// refs (each has an `id`). Append paginated pages by their `skip` offset into one\n// canonical list so loadMore (skip>0, network-only) extends the cache instead of\n// clobbering page 1. A fresh page-1 load (skip 0) replaces the list so pull-to-\n// refresh does not keep a stale tail. Pairs with `keyArgs` which drops\n// limit/skip/sort so all pages of the same (role, criteria) share one cache entry.\nfunction mergeChannelsByUser(existing: any[] | undefined, incoming: any[], { args }: any) {\n const skip = args?.skip ?? 0;\n if (skip === 0) return incoming ?? [];\n const merged = existing ? existing.slice(0) : [];\n (incoming ?? []).forEach((channel: any, index: number) => {\n merged[skip + index] = channel;\n });\n return merged;\n}\n\nfunction mergeMessagesConnection(existing: any, incoming: any, { args }: any) {\n if (!incoming) return existing;\n const skip = args?.skip ?? 0;\n if (skip === 0 || !existing) return incoming;\n\n const mergedData = existing?.data ? existing.data.slice(0) : [];\n const incomingData = incoming?.data ?? [];\n incomingData.forEach((item: any, index: number) => {\n mergedData[skip + index] = item;\n });\n return {\n ...incoming,\n data: mergedData,\n };\n}\n\nexport const typePolicies = {\n Query: {\n fields: {\n // Chat sessions: ignore pagination args so cache stores one canonical list per archive filter\n getAccountChatSessions: {\n keyArgs: ['includeArchived'],\n merge: mergeConnectionEdges,\n },\n // Chat messages (account API): keyed by sessionId, ignore pagination args\n getAccountChatMessages: {\n keyArgs: ['sessionId'],\n merge: mergeConnectionEdges,\n },\n getAccountNewsArticles: {\n keyArgs: ['filter', ['topic']],\n merge: mergeNewsArticlesList,\n },\n // Chat-history channels: one canonical list per (role, criteria)\n // — criteria carries { type, orgName }. Ignore limit/skip/sort so\n // cache-first serves the same list across navigations and loadMore\n // appends instead of replacing.\n channelsByUser: {\n keyArgs: ['role', 'criteria'],\n merge: mergeChannelsByUser,\n },\n // History titles (`editedBy` + type) and thread details (`channelId`)\n // must not share a cache slot. Drop skip/limit so pages merge.\n messages: {\n keyArgs: ['channelId', 'editedBy', 'type', 'props', 'sort', 'parentId'],\n merge: mergeMessagesConnection,\n },\n },\n },\n // `MessengerUser` selects `fullName @client`. With no local resolver the cache\n // cannot satisfy that field, so every UserAccount read is \"incomplete\" — which\n // makes cache-first treat channelsByUser / messages as a miss and refetch on\n // every navigation. Compute fullName locally so the cache reads back complete.\n UserAccount: {\n fields: {\n fullName: {\n read(_existing: string | undefined, { readField }: any): string {\n const given = (readField('givenName') as string | undefined) ?? '';\n const family = (readField('familyName') as string | undefined) ?? '';\n const joined = `${given} ${family}`.replace(/\\s+/g, ' ').trim();\n return joined || (readField('username') as string | undefined) || '';\n },\n },\n },\n },\n};\n"],"names":[],"mappings":"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"}
@@ -148,6 +148,7 @@ function useChatHistorySessionsFromMessages(accountUserId, options) {
148
148
  // Later visits read the cache — no repeated network hit.
149
149
  fetchPolicy: "cache-first",
150
150
  nextFetchPolicy: "cache-first",
151
+ returnPartialData: true,
151
152
  context: {
152
153
  cacheKey: "new-chat-history-messages"
153
154
  }
@@ -366,6 +367,7 @@ function useChatHistorySessionsFromChannels(orgName, options) {
366
367
  // / createChannel cache writes, not per-visit network hits.
367
368
  fetchPolicy: "cache-first",
368
369
  nextFetchPolicy: "cache-first",
370
+ returnPartialData: true,
369
371
  context: {
370
372
  cacheKey: "chat-history-channels-list"
371
373
  }
@@ -382,6 +384,11 @@ function useChatHistorySessionsFromChannels(orgName, options) {
382
384
  sourceChannelCount
383
385
  };
384
386
  }
387
+ function usePrefetchChatHistory(orgName) {
388
+ return useChatHistorySessionsFromChannels(orgName, {
389
+ skip: !orgName
390
+ });
391
+ }
385
392
  function stripModelCostHeader(content) {
386
393
  const normalized = content.replace(/\r\n/g, "\n");
387
394
  return normalized.replace(/^\s*(?:[^\w\n]+\s*)?[a-z0-9][a-z0-9._-]*\s*\(\s*\$[\d.]+\s*\/\s*MTok\s+in\s*\)\s*\n+/i, "");
@@ -777,4 +784,4 @@ function useChatMutations() {
777
784
  saveMessages: sendMessagesLoading
778
785
  }
779
786
  };
780
- }export{AI_ASSISTANT_CHANNELS_QUERY_VARS,HISTORY_PAGE_SIZE,HISTORY_QUERY_BASE,buildSessionFromChannel,chatHistorySessionsFromChannels,chatHistorySessionsFromMessages,enrichHistorySessionsWithUserPrompts,getChatHistoryChannelRefetchQueries,getChatHistoryMessagesQueryVariables,getHistoryChannelsQueryVariables,useChatHistorySessionsFromChannels,useChatHistorySessionsFromMessages,useChatMessages,useChatMutations};//# sourceMappingURL=useChatApi.js.map
787
+ }export{AI_ASSISTANT_CHANNELS_QUERY_VARS,HISTORY_PAGE_SIZE,HISTORY_QUERY_BASE,buildSessionFromChannel,chatHistorySessionsFromChannels,chatHistorySessionsFromMessages,enrichHistorySessionsWithUserPrompts,getChatHistoryChannelRefetchQueries,getChatHistoryMessagesQueryVariables,getHistoryChannelsQueryVariables,useChatHistorySessionsFromChannels,useChatHistorySessionsFromMessages,useChatMessages,useChatMutations,usePrefetchChatHistory};//# sourceMappingURL=useChatApi.js.map