@adminide-stack/yantra-mobile 12.0.31-alpha.7 → 12.0.31-alpha.71
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/LICENSE +71 -21
- package/lib/api/stt.js +11 -15
- package/lib/api/stt.js.map +1 -1
- package/lib/hooks/useChatApi.js +16 -5
- package/lib/hooks/useChatApi.js.map +1 -1
- package/lib/hooks/usePrerequisiteIds.js +8 -12
- package/lib/hooks/usePrerequisiteIds.js.map +1 -1
- package/lib/services/gatewayClient.js +5 -4
- package/lib/services/gatewayClient.js.map +1 -1
- package/package.json +4 -4
package/LICENSE
CHANGED
|
@@ -1,21 +1,71 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Copyright (c)
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
PROPRIETARY SOFTWARE LICENSE AGREEMENT
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 CDEBase Inc. All Rights Reserved.
|
|
4
|
+
|
|
5
|
+
NOTICE TO USER: THIS IS A CONTRACT. BY INSTALLING, COPYING, OR OTHERWISE
|
|
6
|
+
USING THE SOFTWARE, YOU AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE.
|
|
7
|
+
IF YOU DO NOT AGREE TO THE TERMS OF THIS LICENSE, DO NOT INSTALL, COPY,
|
|
8
|
+
OR USE THE SOFTWARE.
|
|
9
|
+
|
|
10
|
+
NO LICENSE GRANTED
|
|
11
|
+
No license, express or implied, is granted to any person or entity.
|
|
12
|
+
All rights are reserved by CDEBase Inc. Any use of this software
|
|
13
|
+
without prior written authorization from CDEBase Inc. is strictly
|
|
14
|
+
prohibited.
|
|
15
|
+
|
|
16
|
+
RESTRICTIONS
|
|
17
|
+
You may NOT:
|
|
18
|
+
a) Copy, modify, adapt, translate, reverse engineer, decompile, or
|
|
19
|
+
disassemble the software or create derivative works based on it
|
|
20
|
+
b) Distribute, sublicense, lease, rent, loan, or otherwise transfer
|
|
21
|
+
the software to any third party
|
|
22
|
+
c) Remove or alter any proprietary notices, labels, or marks on the
|
|
23
|
+
software
|
|
24
|
+
d) Use the software to develop competing products or services
|
|
25
|
+
e) Publicly disclose any benchmarking or performance results
|
|
26
|
+
f) Use the software in any manner that violates applicable laws or
|
|
27
|
+
regulations
|
|
28
|
+
g) Access, view, or use any portion of the source code without
|
|
29
|
+
explicit prior written consent from CDEBase Inc.
|
|
30
|
+
|
|
31
|
+
OWNERSHIP
|
|
32
|
+
This software is the exclusive proprietary property of CDEBase Inc.
|
|
33
|
+
and is protected by copyright laws and international treaty provisions.
|
|
34
|
+
CDEBase Inc. retains all rights, title, and interest in and to the
|
|
35
|
+
software, including all copyrights, patents, trade secrets, trademarks,
|
|
36
|
+
and other intellectual property rights. No rights are transferred or
|
|
37
|
+
conveyed by possession or access to this software.
|
|
38
|
+
|
|
39
|
+
CONFIDENTIALITY
|
|
40
|
+
The software contains trade secrets and proprietary information of
|
|
41
|
+
CDEBase Inc. You agree to maintain strict confidentiality of the
|
|
42
|
+
software and not disclose it, in whole or in part, to any third party
|
|
43
|
+
without prior written consent of CDEBase Inc. This obligation survives
|
|
44
|
+
termination of any agreement with CDEBase Inc.
|
|
45
|
+
|
|
46
|
+
TERMINATION
|
|
47
|
+
Any unauthorized use automatically and immediately terminates all
|
|
48
|
+
permissions. CDEBase Inc. may seek all available legal and equitable
|
|
49
|
+
remedies, including injunctive relief, for any unauthorized use or
|
|
50
|
+
disclosure.
|
|
51
|
+
|
|
52
|
+
WARRANTY DISCLAIMER
|
|
53
|
+
THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
54
|
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
55
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
|
|
56
|
+
NONINFRINGEMENT.
|
|
57
|
+
|
|
58
|
+
LIMITATION OF LIABILITY
|
|
59
|
+
IN NO EVENT SHALL CDEBASE INC. BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
|
|
60
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER ARISING OUT OF THE USE
|
|
61
|
+
OF OR INABILITY TO USE THE SOFTWARE.
|
|
62
|
+
|
|
63
|
+
GOVERNING LAW
|
|
64
|
+
This agreement shall be governed by and construed in accordance with
|
|
65
|
+
the laws of the jurisdiction in which CDEBase Inc. is registered,
|
|
66
|
+
without regard to its conflict of law provisions.
|
|
67
|
+
|
|
68
|
+
For licensing inquiries, contact: legal@cdebase.com
|
|
69
|
+
|
|
70
|
+
CDEBase Inc.
|
|
71
|
+
All Rights Reserved.
|
package/lib/api/stt.js
CHANGED
|
@@ -1,17 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
const BRAIN_STT_URL = "https://cdecli-agent.cdebase.dev/v1/yantra-brain/audio/transcriptions";
|
|
2
2
|
const WHISPER_MODEL = "whisper-large-v3-turbo";
|
|
3
3
|
async function transcribeAudio(params) {
|
|
4
|
-
var _a, _b, _c;
|
|
5
4
|
const {
|
|
6
5
|
uri,
|
|
7
6
|
mimeType = "audio/m4a",
|
|
8
7
|
filename = "audio.m4a",
|
|
9
8
|
prompt
|
|
10
9
|
} = params;
|
|
11
|
-
const apiKey = config.GROQ_API_KEY;
|
|
12
|
-
if (!apiKey) {
|
|
13
|
-
throw new Error("GROQ_API_KEY is not configured. Add it to your .env (e.g. config/development/dev.env).");
|
|
14
|
-
}
|
|
15
10
|
if (!uri) {
|
|
16
11
|
throw new Error("Audio file uri is empty or not provided");
|
|
17
12
|
}
|
|
@@ -25,16 +20,17 @@ async function transcribeAudio(params) {
|
|
|
25
20
|
if (prompt) {
|
|
26
21
|
formData.append("prompt", prompt);
|
|
27
22
|
}
|
|
28
|
-
|
|
23
|
+
return requestTranscription(BRAIN_STT_URL, formData);
|
|
24
|
+
}
|
|
25
|
+
async function requestTranscription(url, formData) {
|
|
26
|
+
var _a, _b, _c;
|
|
27
|
+
const response = await fetch(url, {
|
|
29
28
|
method: "POST",
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
* correctly. Overriding here would break the upload silently.
|
|
36
|
-
*/
|
|
37
|
-
},
|
|
29
|
+
/*
|
|
30
|
+
* Intentionally NOT setting Content-Type. Letting `fetch` derive
|
|
31
|
+
* it from FormData ensures the multipart boundary string is set
|
|
32
|
+
* correctly. Overriding here would break the upload silently.
|
|
33
|
+
*/
|
|
38
34
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
39
35
|
body: formData
|
|
40
36
|
});
|
package/lib/api/stt.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stt.js","sources":["../../src/api/stt.ts"],"sourcesContent":["/**\n * Speech-to-Text (STT) API using Groq's Whisper model — mobile port.\n *\n * Mirrors `packages-modules/account/browser/src/api/stt.ts` (which uploads\n * a `Blob` produced by the browser's `MediaRecorder`). On React Native we\n * upload a file by URI instead, because:\n * • `expo-audio` writes the recording to a local `file://` URI on disk,\n * not an in-memory Blob.\n * • RN's `fetch` + `FormData` already supports `{uri, name, type}` parts —\n * it streams the file directly without us reading bytes into JS, which\n * keeps a 3-minute clip from spiking memory.\n *\n *
|
|
1
|
+
{"version":3,"file":"stt.js","sources":["../../src/api/stt.ts"],"sourcesContent":["/**\n * Speech-to-Text (STT) API using Groq's Whisper model — mobile port.\n *\n * Mirrors `packages-modules/account/browser/src/api/stt.ts` (which uploads\n * a `Blob` produced by the browser's `MediaRecorder`). On React Native we\n * upload a file by URI instead, because:\n * • `expo-audio` writes the recording to a local `file://` URI on disk,\n * not an in-memory Blob.\n * • RN's `fetch` + `FormData` already supports `{uri, name, type}` parts —\n * it streams the file directly without us reading bytes into JS, which\n * keeps a 3-minute clip from spiking memory.\n *\n * Mobile calls ONLY the yantra-brain resource endpoint: the gateway holds\n * the Groq key server-side. A shipped app bundle must never embed a provider\n * key (it cannot be rotated out of installed apps), so unlike web there is\n * NO direct-Groq BYO-key fallback here.\n */\n\nconst BRAIN_STT_URL = 'https://cdecli-agent.cdebase.dev/v1/yantra-brain/audio/transcriptions';\nconst WHISPER_MODEL = 'whisper-large-v3-turbo';\n\nexport interface STTParams {\n /** Local file URI returned by `expo-audio`'s `recorder.uri` (e.g. `file:///...m4a`). */\n uri: string;\n /** Optional MIME type override. HIGH_QUALITY preset → `audio/m4a` on iOS & Android. */\n mimeType?: string;\n /** Optional filename hint sent with the multipart form. Whisper uses the extension to pick a decoder. */\n filename?: string;\n /** Optional Whisper \"prompt\" — passed through to bias decoding. */\n prompt?: string;\n}\n\nexport async function transcribeAudio(params: STTParams): Promise<string> {\n const { uri, mimeType = 'audio/m4a', filename = 'audio.m4a', prompt } = params;\n\n if (!uri) {\n throw new Error('Audio file uri is empty or not provided');\n }\n\n const formData = new FormData();\n /*\n * React Native's FormData accepts file parts in `{uri, name, type}` shape;\n * the runtime streams the file from disk on send. The cast is the usual\n * escape hatch — web FormData's TS lib types only know about\n * `Blob | string`, but the RN polyfill widens it at runtime.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n formData.append('file', { uri, name: filename, type: mimeType } as any);\n formData.append('model', WHISPER_MODEL);\n if (prompt) {\n formData.append('prompt', prompt);\n }\n\n // yantra-brain resource endpoint — the gateway holds the Groq key, the\n // app sends NO Authorization header and ships NO key.\n return requestTranscription(BRAIN_STT_URL, formData);\n}\n\nasync function requestTranscription(url: string, formData: FormData): Promise<string> {\n const response = await fetch(url, {\n method: 'POST',\n /*\n * Intentionally NOT setting Content-Type. Letting `fetch` derive\n * it from FormData ensures the multipart boundary string is set\n * correctly. Overriding here would break the upload silently.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n body: formData as any,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorMessage: string;\n try {\n const errorJson = JSON.parse(errorText);\n errorMessage = errorJson?.error?.message || errorJson?.message || errorText;\n } catch {\n errorMessage = errorText || response.statusText;\n }\n throw new Error(`STT API error (${response.status}): ${errorMessage}`);\n }\n\n const data = (await response.json()) as { text?: string };\n return data?.text?.trim() ?? '';\n}\n"],"names":[],"mappings":"AAkBA,MAAM,aAAgB,GAAA,uEAAA;AACtB,MAAM,aAAgB,GAAA,wBAAA;AAWtB,eAAsB,gBAAgB,MAAoC,EAAA;AACxE,EAAM,MAAA;AAAA,IACJ,GAAA;AAAA,IACA,QAAW,GAAA,WAAA;AAAA,IACX,QAAW,GAAA,WAAA;AAAA,IACX;AAAA,GACE,GAAA,MAAA;AACJ,EAAA,IAAI,CAAC,GAAK,EAAA;AACR,IAAM,MAAA,IAAI,MAAM,yCAAyC,CAAA;AAAA;AAE3D,EAAM,MAAA,QAAA,GAAW,IAAI,QAAS,EAAA;AAQ9B,EAAA,QAAA,CAAS,OAAO,MAAQ,EAAA;AAAA,IACtB,GAAA;AAAA,IACA,IAAM,EAAA,QAAA;AAAA,IACN,IAAM,EAAA;AAAA,GACA,CAAA;AACR,EAAS,QAAA,CAAA,MAAA,CAAO,SAAS,aAAa,CAAA;AACtC,EAAA,IAAI,MAAQ,EAAA;AACV,IAAS,QAAA,CAAA,MAAA,CAAO,UAAU,MAAM,CAAA;AAAA;AAKlC,EAAO,OAAA,oBAAA,CAAqB,eAAe,QAAQ,CAAA;AACrD;AACA,eAAe,oBAAA,CAAqB,KAAa,QAAqC,EAAA;AA9DtF,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AA+DE,EAAM,MAAA,QAAA,GAAW,MAAM,KAAA,CAAM,GAAK,EAAA;AAAA,IAChC,MAAQ,EAAA,MAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOR,IAAM,EAAA;AAAA,GACP,CAAA;AACD,EAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AAChB,IAAM,MAAA,SAAA,GAAY,MAAM,QAAA,CAAS,IAAK,EAAA;AACtC,IAAI,IAAA,YAAA;AACJ,IAAI,IAAA;AACF,MAAM,MAAA,SAAA,GAAY,IAAK,CAAA,KAAA,CAAM,SAAS,CAAA;AACtC,MAAA,YAAA,GAAA,CAAA,CAAe,EAAW,GAAA,SAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,SAAA,CAAA,KAAA,KAAX,IAAkB,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,OAAA,MAAW,uCAAW,OAAW,CAAA,IAAA,SAAA;AAAA,KAC5D,CAAA,OAAA,CAAA,EAAA;AACN,MAAA,YAAA,GAAe,aAAa,QAAS,CAAA,UAAA;AAAA;AAEvC,IAAA,MAAM,IAAI,KAAM,CAAA,CAAA,eAAA,EAAkB,SAAS,MAAM,CAAA,GAAA,EAAM,YAAY,CAAE,CAAA,CAAA;AAAA;AAEvE,EAAM,MAAA,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAK,EAAA;AAGlC,EAAA,OAAA,CAAO,EAAM,GAAA,CAAA,EAAA,GAAA,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAA,IAAA,KAAN,IAAY,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,EAAA,KAAZ,IAAsB,GAAA,EAAA,GAAA,EAAA;AAC/B"}
|
package/lib/hooks/useChatApi.js
CHANGED
|
@@ -83,23 +83,34 @@ function cleanChannelTitle(rawTitle) {
|
|
|
83
83
|
const t = String(rawTitle != null ? rawTitle : "").trim();
|
|
84
84
|
if (!t) return "";
|
|
85
85
|
if (/^(chat[\s-]channel|deep[\s-]search)[\s-][0-9a-f][0-9a-f\s-]{7,}\.?$/i.test(t)) return "";
|
|
86
|
+
if (/^(new chat|workflow|deep search)$/i.test(t)) return "";
|
|
86
87
|
return t;
|
|
87
88
|
}
|
|
89
|
+
const ACTIVE_CONNECTORS_PREFIX_RE = /^\s*\[Active connectors:[^\]]*\]\s*/i;
|
|
90
|
+
function cleanMessageText(raw) {
|
|
91
|
+
return raw.replace(ACTIVE_CONNECTORS_PREFIX_RE, "").trim();
|
|
92
|
+
}
|
|
88
93
|
function buildSessionFromChannel(channel) {
|
|
89
|
-
var _a, _b, _c;
|
|
94
|
+
var _a, _b, _c, _d;
|
|
90
95
|
const channelId = String((_a = channel == null ? void 0 : channel.id) != null ? _a : "");
|
|
91
96
|
if (!channelId) return null;
|
|
92
97
|
const lastMessage = (_b = channel == null ? void 0 : channel.lastMessage) != null ? _b : null;
|
|
93
98
|
const lastMessageRole = getLastMessageRole(lastMessage);
|
|
94
99
|
const parentUserPrompt = getParentUserPrompt(lastMessage);
|
|
95
|
-
const parentTrimmed = parentUserPrompt
|
|
96
|
-
const userTurn = lastMessageRole === "USER" && (lastMessage == null ? void 0 : lastMessage.message) ? String(lastMessage.message)
|
|
100
|
+
const parentTrimmed = cleanMessageText(parentUserPrompt);
|
|
101
|
+
const userTurn = lastMessageRole === "USER" && (lastMessage == null ? void 0 : lastMessage.message) ? cleanMessageText(String(lastMessage.message)) : "";
|
|
97
102
|
const cleanedChannelTitle = cleanChannelTitle(channel == null ? void 0 : channel.title);
|
|
98
103
|
const cleanedDisplayName = cleanChannelTitle(channel == null ? void 0 : channel.displayName);
|
|
99
|
-
let resolvedTitle =
|
|
104
|
+
let resolvedTitle = cleanedChannelTitle || parentTrimmed || userTurn || cleanedDisplayName;
|
|
105
|
+
if (!resolvedTitle) {
|
|
106
|
+
const rawDefault = String((_c = channel == null ? void 0 : channel.title) != null ? _c : "").trim();
|
|
107
|
+
if (rawDefault && !/^(chat[\s-]channel|deep[\s-]search)[\s-][0-9a-f][0-9a-f\s-]{7,}\.?$/i.test(rawDefault)) {
|
|
108
|
+
resolvedTitle = rawDefault;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
100
111
|
const isPlaceholder = !resolvedTitle;
|
|
101
112
|
if (isPlaceholder) resolvedTitle = "Thinking\u2026";
|
|
102
|
-
const rawPreview = String((
|
|
113
|
+
const rawPreview = String((_d = lastMessage == null ? void 0 : lastMessage.message) != null ? _d : "").replace(/\s+/g, " ").trim();
|
|
103
114
|
let preview = rawPreview;
|
|
104
115
|
if (preview && preview === parentTrimmed) preview = "";
|
|
105
116
|
const sortAt = (() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useChatApi.js","sources":["../../src/hooks/useChatApi.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { AiAgentMessageRole, PostTypeEnum, RoomType, SortEnum } from 'common';\nimport {\n GetChannelsByUserWithLastMessageDocument,\n useAddChannelMutation,\n useGetChannelsByUserWithLastMessageQuery,\n useMessagesQuery,\n useSendMessagesMutation,\n} from 'common/graphql';\nimport type {\n IAccountCreateChatSessionInput,\n IAccountSaveChatMessagesInput as IAccountSaveChatMessagesInputBase,\n} from 'common/server';\nimport { useCallback, useMemo } from 'react';\nimport { v4 as uuidv4 } from 'uuid';\n\nconst MESSAGES_PAGE_LIMIT = 100;\n\n/** Same variables as web Inbox / AIAgent: list AI assistant channels for the current user. */\nexport const AI_ASSISTANT_CHANNELS_QUERY_VARS = {\n criteria: { type: RoomType.Aiassistant },\n limit: 100,\n skip: 0,\n sort: { key: 'updatedAt', value: SortEnum.Desc },\n};\n\nexport const HISTORY_PAGE_SIZE = 20;\n\n/**\n * Variables for the channels-based chat history list (`ChatHistoryLanding`).\n *\n * IMPORTANT: pass the user's org `slug` (e.g. `tarun-upadhyay-qraw`) so the\n * `channelsByUser` resolver's `$in: [criteria.orgName, orgId]` includes\n * channels stored under the slug. When `criteria.orgName` is omitted, the\n * `$in` collapses to just `[orgId]` and channels saved with the slug as\n * `orgName` (the mobile create path) never match. That's the cause of the\n * silently-empty history screen.\n *\n * Kept as a builder (not a constant) because the slug varies per user and\n * because Apollo treats different `variables` as different cached entries —\n * if the create mutation refetches a no-orgName variant, the orgName-variant\n * the screen watches stays stale.\n */\nexport function getHistoryChannelsQueryVariables(orgName?: string | null, options?: { skip?: number; limit?: number }) {\n const trimmedOrg = typeof orgName === 'string' && orgName.trim().length > 0 ? orgName.trim() : undefined;\n return {\n criteria: {\n type: RoomType.Aiassistant,\n ...(trimmedOrg ? { orgName: trimmedOrg } : {}),\n },\n limit: options?.limit ?? HISTORY_PAGE_SIZE,\n skip: options?.skip ?? 0,\n sort: { key: 'updatedAt' as const, value: SortEnum.Desc },\n };\n}\n\n/** @deprecated Use {@link getHistoryChannelsQueryVariables} so `orgName` is included. */\nexport const HISTORY_QUERY_BASE = getHistoryChannelsQueryVariables();\n\n/**\n * Variables for the chat-history feed on the mobile `ChatHistory` screen.\n *\n * First page uses `HISTORY_PAGE_SIZE` (20) posts; \"Load older\" paginates by post\n * `skip` in increments of 20. Rows are still one per channel (collapsed from posts).\n *\n * This query intentionally hits `messages` (not `channelsByUser`) — the same\n * pattern the web sidebar uses (`useNewChatPageHistorySessions`). Reasons:\n * 1. `channelsByUser` is server-side gated by an injected `orgName` /\n * `members` filter that can mismatch when channels were stored with an\n * org slug while the resolver injects the org id. The `messages`\n * resolver filters Post directly by `editedBy: accountId`, so the\n * user's own AI-assistant posts always show up.\n * 2. The user-authored post IS the conversation's natural title — no need\n * to walk `lastMessage.propsConfiguration.contents.parent` to recover\n * the original prompt.\n *\n * - `type: AIASSISTANT` scopes to AI chat (not direct/service rooms).\n * - `props.role: 'user'` selects only the user's turns. The assistant reply\n * is ignored here; it would override the title with the agent's words.\n * - `editedBy: accountUserId` scopes to the current user's own posts,\n * independent of channel membership / org name.\n */\nexport function getChatHistoryMessagesQueryVariables(\n accountUserId: string,\n options?: { skip?: number; limit?: number },\n) {\n return {\n limit: options?.limit ?? HISTORY_PAGE_SIZE,\n skip: options?.skip ?? 0,\n sort: { key: 'updatedAt' as const, value: SortEnum.Desc },\n type: PostTypeEnum.Aiassistant,\n editedBy: accountUserId,\n props: { role: 'user' },\n };\n}\n\nexport type ChatHistoryMode = 'chat' | 'deep-search';\n\nexport interface ChatHistorySession {\n /** Channel id — used to navigate to the Chat screen. */\n channelId: string;\n /** User's most recent prompt in this channel (used as the row title). */\n title: string;\n /** Second line: latest post `message` field (same as Manus subtitle). */\n preview: string;\n /** Conversation mode (chat / deep-search), inferred from channel display name / title. */\n mode: ChatHistoryMode;\n /** Most-recent activity timestamp (sort key + bucket key for Today/Yesterday/…). */\n updatedAt: Date;\n createdAt: Date;\n /**\n * True when no concrete prompt was recoverable (no parent, no user turn, no\n * meaningful channel.title). UI renders the title in a quieter style.\n */\n isPlaceholder: boolean;\n}\n\n/**\n * Collapse a list of user-authored AI assistant posts (newest first) into one\n * row per channel. First post per `channel.id` wins the title, which — because\n * the query is sorted by `updatedAt DESC` — is the user's latest prompt in\n * that channel. Posts whose `channel.id` is missing (unexpected, but possible\n * if the resolver omits the relation) are skipped.\n */\nexport function chatHistorySessionsFromMessages(\n data: { messages?: { data?: unknown[] | null } | null } | null | undefined,\n): ChatHistorySession[] {\n const rows = data?.messages?.data;\n if (!rows?.length) return [];\n\n const seen = new Set<string>();\n const sessions: ChatHistorySession[] = [];\n\n for (const post of rows as any[]) {\n const channelId = post?.channel?.id ? String(post.channel.id) : '';\n if (channelId && !seen.has(channelId)) {\n seen.add(channelId);\n\n const rawTitle = String(post?.message ?? '')\n .replace(/\\s+/g, ' ')\n .trim();\n const updatedAt = post?.updatedAt ? new Date(post.updatedAt) : new Date();\n const createdAt = post?.createdAt ? new Date(post.createdAt) : updatedAt;\n const title = rawTitle || 'New chat';\n\n sessions.push({\n channelId,\n title,\n preview: '',\n mode: 'chat',\n updatedAt,\n createdAt,\n isPlaceholder: !rawTitle,\n });\n }\n }\n\n return sessions;\n}\n\n/**\n * Mobile parity hook for the web sidebar's `useNewChatPageHistorySessions`.\n *\n * Returns one row per channel where the user has authored at least one AI assistant\n * post, with the title taken from that user's latest prompt. Skipped when\n * `accountUserId` isn't known yet (we don't want to fire a query without it).\n */\nexport function useChatHistorySessionsFromMessages(\n accountUserId: string | null | undefined,\n options?: { skip?: boolean },\n) {\n const skip = options?.skip || !accountUserId;\n const { data, loading, error, refetch } = useMessagesQuery({\n variables: accountUserId ? getChatHistoryMessagesQueryVariables(accountUserId) : undefined,\n skip,\n fetchPolicy: 'cache-and-network',\n notifyOnNetworkStatusChange: true,\n context: { cacheKey: 'new-chat-history-messages' },\n });\n\n const sessions = useMemo(() => chatHistorySessionsFromMessages(data), [data]);\n const sourcePostCount = data?.messages?.data?.length ?? 0;\n\n return { sessions, loading, error, refetch, sourcePostCount };\n}\n\n/* -------------------------------------------------------------------------- */\n/* Channels-based chat history (parent + lastMessage) */\n/* -------------------------------------------------------------------------- */\n\ninterface ChannelLastMessageLike {\n message?: string | null;\n createdAt?: string | null;\n updatedAt?: string | null;\n props?: { role?: string | null } | null;\n propsConfiguration?: {\n contents?: {\n role?: string | null;\n parent?: {\n message?: string | null;\n props?: { role?: string | null } | null;\n } | null;\n } | null;\n content?: { role?: string | null } | null;\n } | null;\n}\n\ninterface ChannelLike {\n id?: string | null;\n type?: string | null;\n displayName?: string | null;\n title?: string | null;\n createdAt?: string | null;\n updatedAt?: string | null;\n lastMessage?: ChannelLastMessageLike | null;\n}\n\nfunction getLastMessageRole(lastMessage: ChannelLastMessageLike | null | undefined): string {\n return String(\n lastMessage?.propsConfiguration?.contents?.role ??\n lastMessage?.propsConfiguration?.content?.role ??\n lastMessage?.props?.role ??\n '',\n ).toUpperCase();\n}\n\nfunction getParentUserPrompt(lastMessage: ChannelLastMessageLike | null | undefined): string {\n const parent = lastMessage?.propsConfiguration?.contents?.parent;\n if (!parent) return '';\n return String(parent?.message ?? '').trim();\n}\n\nfunction detectMode(channel: ChannelLike): ChatHistoryMode {\n const display = String(channel?.displayName ?? '').toLowerCase();\n const title = String(channel?.title ?? '').toLowerCase();\n if (display.startsWith('deep-search') || title.startsWith('deep search') || title.startsWith('deep-search')) {\n return 'deep-search';\n }\n return 'chat';\n}\n\n/**\n * Drop the internal slug we use as `channel.title` for server-side mode detection\n * (`chat-channel-<uuid>` / `deep-search-<uuid>`) so it doesn't leak into the row\n * label. The server sometimes also reformats this slug into `displayName` as\n * title-cased text with spaces (e.g. `\"Deep Search b64be4f7 9fe6 …\"`) — those\n * are equally machine-generated and must NOT be shown to the user.\n *\n * Pattern accepts:\n * • `deep-search-<uuid>` / `chat-channel-<uuid>` (raw, mode signal)\n * • `Deep Search <uuid>` / `Chat Channel <uuid>` (display-cased, server-reformatted)\n * • UUID may use hyphens, spaces, or be partially truncated as long as the\n * trailing chunk is hex.\n */\nfunction cleanChannelTitle(rawTitle: string | null | undefined): string {\n const t = String(rawTitle ?? '').trim();\n if (!t) return '';\n if (/^(chat[\\s-]channel|deep[\\s-]search)[\\s-][0-9a-f][0-9a-f\\s-]{7,}\\.?$/i.test(t)) return '';\n return t;\n}\n\n/**\n * Map one channel into a session row (Manus-style two-line list):\n *\n * **Title (line 1):** `lastMessage.propsConfiguration.contents.parent.message`\n * when present (the user turn the thread is anchored on). Otherwise fall back\n * to the last post body if that post is still a user message, then a\n * machine-slug-stripped channel title, then a machine-slug-stripped\n * `displayName`, then `\"Thinking…\"`. Machine slugs (`deep-search-<uuid>`,\n * `chat-channel-<uuid>`, and their server-reformatted display variants)\n * are filtered via `cleanChannelTitle`, so they never reach the row.\n *\n * **Preview (line 2):** `lastMessage.message` as returned by the API (trimmed,\n * whitespace collapsed). Agent errors that start with `⚠` stay visible in the\n * subtitle, matching the reference UI.\n *\n * If preview text equals the title after trim, the second line is omitted\n * (single-line channel, no duplicate).\n */\nexport function buildSessionFromChannel(channel: ChannelLike): ChatHistorySession | null {\n const channelId = String(channel?.id ?? '');\n if (!channelId) return null;\n\n const lastMessage = channel?.lastMessage ?? null;\n const lastMessageRole = getLastMessageRole(lastMessage);\n const parentUserPrompt = getParentUserPrompt(lastMessage);\n const parentTrimmed = parentUserPrompt.trim();\n\n const userTurn = lastMessageRole === 'USER' && lastMessage?.message ? String(lastMessage.message).trim() : '';\n const cleanedChannelTitle = cleanChannelTitle(channel?.title);\n /**\n * Apply the same machine-slug cleaner to `displayName`. The server\n * sometimes derives displayName from the title (`\"deep-search-<uuid>\"`\n * → `\"Deep Search <uuid>\"`), so without this the slug bypasses\n * `cleanedChannelTitle` and lands directly in the row label.\n */\n const cleanedDisplayName = cleanChannelTitle(channel?.displayName);\n\n let resolvedTitle = parentTrimmed || userTurn || cleanedChannelTitle || cleanedDisplayName;\n const isPlaceholder = !resolvedTitle;\n /**\n * When every signal fails — typical when a send just landed and the\n * server hasn't yet persisted the message that would populate\n * `propsConfiguration.contents.parent.message` — show `\"Thinking…\"`\n * instead of an empty label or the raw machine slug. The row's mode\n * tile still signals chat vs deep-search, so the user has enough\n * context to recognize the entry without leaking implementation noise.\n */\n if (isPlaceholder) resolvedTitle = 'Thinking…';\n\n const rawPreview = String(lastMessage?.message ?? '')\n .replace(/\\s+/g, ' ')\n .trim();\n let preview = rawPreview;\n if (preview && preview === parentTrimmed) preview = '';\n\n const sortAt = (() => {\n const candidates = [channel?.updatedAt, lastMessage?.updatedAt, lastMessage?.createdAt, channel?.createdAt];\n for (const candidate of candidates) {\n if (candidate) {\n const t = new Date(candidate).getTime();\n if (Number.isFinite(t) && t > 0) return t;\n }\n }\n return Date.now();\n })();\n\n const createdAtRaw = channel?.createdAt ? new Date(channel.createdAt).getTime() : sortAt;\n\n return {\n channelId,\n title: resolvedTitle,\n preview,\n mode: detectMode(channel),\n updatedAt: new Date(sortAt),\n createdAt: new Date(Number.isFinite(createdAtRaw) ? createdAtRaw : sortAt),\n isPlaceholder,\n };\n}\n\n/** Collapse a `channelsByUser` response into session rows for the history list. */\nexport function chatHistorySessionsFromChannels(\n data: { channelsByUser?: (ChannelLike | null)[] | null } | null | undefined,\n): ChatHistorySession[] {\n const channels = (data?.channelsByUser ?? []) as (ChannelLike | null)[];\n return channels\n .filter((c): c is ChannelLike => Boolean(c?.id) && (!c?.type || c.type === RoomType.Aiassistant))\n .map((c) => buildSessionFromChannel(c))\n .filter((row): row is ChatHistorySession => row !== null)\n .sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime());\n}\n\n/**\n * Chat history feed driven by `channelsByUser`. Each row: parent prompt as title,\n * `lastMessage.message` as subtitle (Manus-style), when the API provides them.\n *\n * Caller MUST pass `orgName` (the org slug). Without it, the resolver only\n * matches channels whose `orgName` field equals the user's `orgId`, which is\n * never the case for mobile-created channels (those store the slug). The hook\n * suspends the query (`skip: true`) until `orgName` is known, so we never\n * fire a guaranteed-empty request.\n *\n * Pagination is by channel count (one channel = one row in this query),\n * unlike the messages-based path which paginates by raw post rows.\n */\nexport function useChatHistorySessionsFromChannels(orgName: string | null | undefined, options?: { skip?: boolean }) {\n const skip = options?.skip || !orgName;\n const variables = useMemo(() => getHistoryChannelsQueryVariables(orgName), [orgName]);\n\n const { data, loading, error, refetch } = useGetChannelsByUserWithLastMessageQuery({\n variables,\n skip,\n fetchPolicy: 'cache-and-network',\n notifyOnNetworkStatusChange: true,\n context: { cacheKey: 'chat-history-channels-list' },\n });\n\n const sessions = useMemo(() => chatHistorySessionsFromChannels(data), [data]);\n const sourceChannelCount = data?.channelsByUser?.length ?? 0;\n /**\n * `sessionsLoaded` means \"we have data we can show\", regardless of whether a\n * background revalidation is still in flight. Same contract as `messagesLoaded`\n * in `useChatMessages` — lets the screen show the cached list (or empty state)\n * immediately on revisit instead of flashing a loader for the network round-trip.\n */\n const sessionsLoaded = data !== undefined;\n\n return { sessions, loading, sessionsLoaded, error, refetch, sourceChannelCount };\n}\n\nfunction stripModelCostHeader(content: string): string {\n const normalized = content.replace(/\\r\\n/g, '\\n');\n return normalized.replace(\n /^\\s*(?:[^\\w\\n]+\\s*)?[a-z0-9][a-z0-9._-]*\\s*\\(\\s*\\$[\\d.]+\\s*\\/\\s*MTok\\s+in\\s*\\)\\s*\\n+/i,\n '',\n );\n}\n\nfunction sanitizeAssistantContentByRole(role: unknown, content: string): string {\n return role === 'assistant' ? stripModelCostHeader(content) : content;\n}\n\nfunction omitContent<T extends Record<string, any>>(value: T | null | undefined): Omit<T, 'content'> {\n const clone = { ...(value ?? {}) } as Record<string, any>;\n delete clone.content;\n return clone as Omit<T, 'content'>;\n}\n\nexport interface ChatSessionUI {\n id: string;\n title: string;\n createdAt: Date;\n updatedAt: Date;\n messageCount?: number;\n}\n\nexport function useChatSessions(options?: { includeArchived?: boolean; skip?: boolean }) {\n const { data, loading, error, refetch } = useGetChannelsByUserWithLastMessageQuery({\n variables: AI_ASSISTANT_CHANNELS_QUERY_VARS,\n skip: options?.skip,\n fetchPolicy: 'cache-and-network',\n });\n\n const sessions: ChatSessionUI[] = useMemo(() => {\n const channels = data?.channelsByUser ?? [];\n return channels\n .filter((c): c is NonNullable<typeof c> => Boolean(c?.id))\n .map((channel) => ({\n id: channel.id,\n title: channel.title || channel.displayName || 'New Chat',\n createdAt: new Date(channel.createdAt ?? Date.now()),\n updatedAt: new Date(channel.updatedAt ?? Date.now()),\n messageCount: undefined,\n }));\n }, [data]);\n\n return { sessions, loading, error, refetch };\n}\n\nexport interface ChatMessageUI {\n id: string;\n sessionId: string;\n role: 'user' | 'assistant' | 'system';\n content: string;\n attachments?: Array<{ id: string; name: string; type: string; mimeType?: string; size?: number; url?: string }>;\n tokenCount?: number;\n model?: string;\n createdAt: Date;\n updatedAt: Date;\n}\n\ninterface MinimalFile {\n id?: string | null;\n name?: string | null;\n mimeType?: string | null;\n size?: number | null;\n url?: string | null;\n}\n\ninterface MinimalPost {\n id?: string | null;\n message?: string | null;\n createdAt?: string | null;\n updatedAt?: string | null;\n channel?: { id?: string | null } | null;\n files?: { data?: MinimalFile[] | null } | null;\n props?: { role?: string | null; tokenCount?: number | null; model?: string | null } | null;\n propsConfiguration?: {\n contents?: { role?: string | null } | null;\n content?: { role?: string | null } | null;\n } | null;\n}\n\nfunction mapPostToChatMessageUI(post: MinimalPost, fallbackChannelId: string): ChatMessageUI {\n const props = (post.props ?? {}) as Record<string, any>;\n const contents = post.propsConfiguration?.contents ?? {};\n const roleRaw = props.role ?? contents.role ?? post.propsConfiguration?.content?.role;\n let role: ChatMessageUI['role'] = 'assistant';\n if (roleRaw === 'user' || roleRaw === AiAgentMessageRole.User) role = 'user';\n else if (roleRaw === 'assistant' || roleRaw === AiAgentMessageRole.Assistant) role = 'assistant';\n else if (roleRaw === 'system') role = 'system';\n\n const rawContent = post?.message ?? '';\n const content = sanitizeAssistantContentByRole(role, rawContent);\n\n return {\n id: post?.id ?? uuidv4(),\n sessionId: post?.channel?.id ?? fallbackChannelId,\n role,\n content,\n attachments: (post?.files?.data ?? []).map((file) => ({\n id: file.id ?? uuidv4(),\n name: file.name ?? 'file',\n type: typeof file.mimeType === 'string' && file.mimeType.startsWith('image/') ? 'screenshot' : 'file',\n mimeType: file.mimeType ?? undefined,\n size: file.size ?? undefined,\n url: file.url ?? undefined,\n })),\n tokenCount: props.tokenCount ?? undefined,\n model: props.model ?? undefined,\n createdAt: post?.createdAt ? new Date(post.createdAt) : new Date(),\n updatedAt: post?.updatedAt ? new Date(post.updatedAt) : new Date(),\n };\n}\n\nexport function useChatMessages(sessionId: string | null, options?: { skip?: boolean }) {\n const { data, loading, error, refetch } = useMessagesQuery({\n variables: {\n channelId: sessionId ?? undefined,\n parentId: null,\n limit: MESSAGES_PAGE_LIMIT,\n skip: 0,\n },\n skip: !sessionId || options?.skip,\n fetchPolicy: 'cache-and-network',\n notifyOnNetworkStatusChange: true,\n /**\n * Cache key is per-channel so switching sessions doesn't read another channel's response.\n * Keeping this as a constant ('messages-list') used to cause cross-session bleed in the\n * custom Apollo link before reaching the normalized cache.\n */\n context: { cacheKey: sessionId ? `messages-list:${sessionId}` : 'messages-list' },\n });\n\n /**\n * `messagesLoaded` means \"we have data we can show\", regardless of whether a\n * background revalidation is in flight. With `cache-and-network`, Apollo\n * fills `data` from cache synchronously while `loading` is still true for\n * the network round-trip — gating hydration on `!loading` made every chat\n * revisit show a loader for the network latency even though the messages\n * were already cached. The chat stream re-hydrates whenever `data` changes,\n * so the fresh network response still swaps in silently afterward.\n */\n const messagesLoaded = data !== undefined;\n\n const messages: ChatMessageUI[] = useMemo(() => {\n if (!sessionId) return [];\n const rows = data?.messages?.data ?? [];\n return rows\n .map((post) => mapPostToChatMessageUI(post as MinimalPost, sessionId))\n .sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());\n }, [data, sessionId]);\n\n return { messages, loading, messagesLoaded, error, refetch };\n}\n\nexport type IAccountSaveChatMessagesInput = IAccountSaveChatMessagesInputBase & {\n mode?: 'plan' | 'build';\n createdBy?: string;\n};\n\n/** Backend/gateway may have already inserted the post (E11000 duplicate `_id`). */\nfunction isDuplicatePostError(error: unknown): boolean {\n const parts: string[] = [];\n if (error && typeof error === 'object' && 'graphQLErrors' in error) {\n const gqlErrors = (error as { graphQLErrors?: Array<{ message?: string }> }).graphQLErrors ?? [];\n parts.push(...gqlErrors.map((e) => e?.message ?? ''));\n }\n if (error instanceof Error) {\n parts.push(error.message);\n } else if (error != null) {\n parts.push(String(error));\n }\n const msg = parts.join(' ');\n return /E11000|duplicate key/i.test(msg);\n}\n\nexport function useChatMutations() {\n const [addChannelMutation, { loading: createChannelLoading }] = useAddChannelMutation();\n const [sendMessagesMutation, { loading: sendMessagesLoading }] = useSendMessagesMutation();\n\n const createChannel = useCallback(\n async (input?: IAccountCreateChatSessionInput): Promise<ChatSessionUI> => {\n const {\n orgName: orgNameArg,\n projectId: projectIdArg,\n ...inputForSettings\n } = (input ?? {}) as IAccountCreateChatSessionInput & {\n orgName?: string | null;\n projectId?: string | null;\n };\n const orgName =\n typeof orgNameArg === 'string' && orgNameArg.trim().length > 0 ? orgNameArg.trim() : undefined;\n const projectId =\n typeof projectIdArg === 'string' && projectIdArg.trim().length > 0 ? projectIdArg.trim() : undefined;\n\n const settings = {\n title: input?.title ?? 'New Chat',\n description: input?.systemPrompt ?? null,\n isShared: false,\n sharedSlug: null,\n isArchived: false,\n isPinned: false,\n model: input?.model ?? null,\n systemPrompt: input?.systemPrompt ?? null,\n ...inputForSettings,\n };\n\n const { data } = await addChannelMutation({\n variables: {\n channelId: input?.id ?? null,\n name: input?.title ?? 'New Chat',\n description: input?.systemPrompt ?? null,\n type: RoomType.Aiassistant,\n settings,\n ...(orgName ? { orgName } : {}),\n ...(projectId ? { projectId } : {}),\n },\n /**\n * Refetch every cache slot the rest of the app is watching for\n * channel lists. Apollo keys cached results by `variables`, so each\n * shape we emit here must match a watched query exactly.\n *\n * Variants:\n * 1. Legacy limit:100 list (web parity, no `criteria.orgName`).\n * 2. Mobile history-screen variant WITH `criteria.orgName` so the\n * resolver's `$in: [slug, orgId]` matches mobile-created channels.\n * 3. Same variant WITHOUT orgName, in case the screen mounted before\n * org settings resolved.\n */\n refetchQueries: [\n { query: GetChannelsByUserWithLastMessageDocument, variables: AI_ASSISTANT_CHANNELS_QUERY_VARS },\n ...(orgName\n ? [\n {\n query: GetChannelsByUserWithLastMessageDocument,\n variables: getHistoryChannelsQueryVariables(orgName),\n },\n ]\n : []),\n { query: GetChannelsByUserWithLastMessageDocument, variables: HISTORY_QUERY_BASE },\n ],\n awaitRefetchQueries: true,\n });\n\n if (!data?.createChannel?.id) {\n throw new Error('Failed to create channel');\n }\n\n const channel = data.createChannel;\n const title = channel.title ?? input?.title ?? 'New Chat';\n const now = new Date();\n\n return {\n id: channel.id,\n title,\n createdAt: now,\n updatedAt: now,\n };\n },\n [addChannelMutation],\n );\n\n const saveMessages = useCallback(\n async (\n input: IAccountSaveChatMessagesInput,\n ): Promise<{\n userMessage: ChatMessageUI;\n assistantMessage: ChatMessageUI;\n session: ChatSessionUI;\n }> => {\n const sanitizedAssistantContent = stripModelCostHeader(input.assistantMessage.content ?? '');\n const assistantMessageWithoutContent = omitContent((input.assistantMessage as any) ?? {});\n\n let userPost: MinimalPost | null | undefined;\n try {\n const userResult = await sendMessagesMutation({\n variables: {\n channelId: input.sessionId,\n type: RoomType.Aiassistant,\n content: input.userMessage.content ?? '',\n ...(input.createdBy ? { createdBy: input.createdBy } : {}),\n extraProps: {\n type: PostTypeEnum.Aiassistant,\n role: 'user',\n attachments: input.userMessage.attachments ?? [],\n isActive: true,\n status: 'complete',\n ...(input.userMessage as any),\n ...(input.mode ? { mode: input.mode } : {}),\n },\n } as any,\n });\n userPost = userResult.data?.sendMessage as MinimalPost | undefined;\n } catch (err) {\n if (!isDuplicatePostError(err)) {\n throw err;\n }\n console.warn('[saveMessages] user post already persisted (skipping duplicate insert)');\n }\n\n /**\n * Keep the prompting user post id in metadata. `sendMessage.postId` is the id of\n * the post being created, so reusing the user post id for the assistant reply would\n * collide and leave only the user message persisted.\n */\n const userPostId = userPost?.id ?? null;\n\n let assistantPost: MinimalPost | null | undefined;\n try {\n const assistantResult = await sendMessagesMutation({\n variables: {\n channelId: input.sessionId,\n type: RoomType.Aiassistant,\n content: sanitizedAssistantContent,\n extraProps: {\n type: PostTypeEnum.Aiassistant,\n role: 'assistant',\n attachments: input.assistantMessage.attachments ?? [],\n tokenCount: input.assistantMessage.tokenCount,\n latencyMs: input.assistantMessage.latencyMs,\n model: input.assistantMessage.model,\n finishReason: (input.assistantMessage as any).finishReason ?? null,\n isActive: true,\n status: 'complete',\n ...assistantMessageWithoutContent,\n ...(userPostId ? { parentId: userPostId } : {}),\n ...(input.mode ? { mode: input.mode } : {}),\n },\n } as any,\n });\n assistantPost = assistantResult.data?.sendMessage as MinimalPost | undefined;\n } catch (err) {\n if (!isDuplicatePostError(err)) {\n throw err;\n }\n console.warn('[saveMessages] assistant post already persisted (skipping duplicate insert)');\n }\n\n if (!userPost && !assistantPost) {\n throw new Error('Failed to send messages');\n }\n\n const now = new Date();\n const fallbackUser: ChatMessageUI = {\n id: userPostId ?? uuidv4(),\n sessionId: input.sessionId,\n role: 'user',\n content: input.userMessage.content ?? '',\n createdAt: now,\n updatedAt: now,\n };\n const fallbackAssistant: ChatMessageUI = {\n id: uuidv4(),\n sessionId: input.sessionId,\n role: 'assistant',\n content: sanitizedAssistantContent,\n createdAt: now,\n updatedAt: now,\n tokenCount: input.assistantMessage.tokenCount,\n model: input.assistantMessage.model,\n };\n return {\n userMessage: userPost ? mapPostToChatMessageUI(userPost, input.sessionId) : fallbackUser,\n assistantMessage: assistantPost\n ? mapPostToChatMessageUI(assistantPost, input.sessionId)\n : fallbackAssistant,\n session: {\n id: input.sessionId,\n title: 'Chat',\n createdAt: now,\n updatedAt: now,\n },\n };\n },\n [sendMessagesMutation],\n );\n\n return {\n createChannel,\n createSession: createChannel,\n saveMessages,\n loading: { create: createChannelLoading, saveMessages: sendMessagesLoading },\n };\n}\n"],"names":["uuidv4","_a","_b","_c","_d","_e"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,MAAM,mBAAsB,GAAA,GAAA;AAGrB,MAAM,gCAAmC,GAAA;AAAA,EAC9C,QAAU,EAAA;AAAA,IACR,MAAM,QAAS,CAAA;AAAA,GACjB;AAAA,EACA,KAAO,EAAA,GAAA;AAAA,EACP,IAAM,EAAA,CAAA;AAAA,EACN,IAAM,EAAA;AAAA,IACJ,GAAK,EAAA,WAAA;AAAA,IACL,OAAO,QAAS,CAAA;AAAA;AAEpB;AACO,MAAM,iBAAoB,GAAA;AAiBjB,SAAA,gCAAA,CAAiC,SAAyB,OAGvE,EAAA;AAxCH,EAAA,IAAA,EAAA,EAAA,EAAA;AAyCE,EAAM,MAAA,UAAA,GAAa,OAAO,OAAA,KAAY,QAAY,IAAA,OAAA,CAAQ,IAAK,EAAA,CAAE,MAAS,GAAA,CAAA,GAAI,OAAQ,CAAA,IAAA,EAAS,GAAA,MAAA;AAC/F,EAAO,OAAA;AAAA,IACL,QAAU,EAAA,cAAA,CAAA;AAAA,MACR,MAAM,QAAS,CAAA;AAAA,KAAA,EACX,UAAa,GAAA;AAAA,MACf,OAAS,EAAA;AAAA,QACP,EAAC,CAAA;AAAA,IAEP,KAAA,EAAA,CAAO,EAAS,GAAA,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAA,KAAA,KAAT,IAAkB,GAAA,EAAA,GAAA,iBAAA;AAAA,IACzB,IAAA,EAAA,CAAM,EAAS,GAAA,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAA,IAAA,KAAT,IAAiB,GAAA,EAAA,GAAA,CAAA;AAAA,IACvB,IAAM,EAAA;AAAA,MACJ,GAAK,EAAA,WAAA;AAAA,MACL,OAAO,QAAS,CAAA;AAAA;AAClB,GACF;AACF;AAGO,MAAM,qBAAqB,gCAAiC;AA4KnE,SAAS,mBAAmB,WAAgE,EAAA;AAvO5F,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AAwOE,EAAO,OAAA,MAAA,CAAA,CAAO,wEAAa,kBAAb,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAiC,aAAjC,IAA2C,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,KAA3C,IAAmD,GAAA,EAAA,GAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,WAAA,IAAA,IAAA,GAAA,MAAA,GAAA,WAAA,CAAa,kBAAb,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAiC,YAAjC,IAA0C,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,KAA7F,aAAqG,EAAa,GAAA,WAAA,IAAA,IAAA,GAAA,MAAA,GAAA,WAAA,CAAA,KAAA,KAAb,mBAAoB,IAAzH,KAAA,IAAA,GAAA,EAAA,GAAiI,EAAE,CAAA,CAAE,WAAY,EAAA;AACjK;AACA,SAAS,oBAAoB,WAAgE,EAAA;AA1O7F,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AA2OE,EAAA,MAAM,MAAS,GAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,WAAA,IAAA,IAAA,GAAA,MAAA,GAAA,WAAA,CAAa,kBAAb,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAiC,aAAjC,IAA2C,GAAA,MAAA,GAAA,EAAA,CAAA,MAAA;AAC1D,EAAI,IAAA,CAAC,QAAe,OAAA,EAAA;AACpB,EAAA,OAAO,QAAO,EAAQ,GAAA,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAA,OAAA,KAAR,IAAmB,GAAA,EAAA,GAAA,EAAE,EAAE,IAAK,EAAA;AAC5C;AACA,SAAS,WAAW,OAAuC,EAAA;AA/O3D,EAAA,IAAA,EAAA,EAAA,EAAA;AAgPE,EAAA,MAAM,UAAU,MAAO,CAAA,CAAA,EAAA,GAAA,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAS,gBAAT,IAAwB,GAAA,EAAA,GAAA,EAAE,EAAE,WAAY,EAAA;AAC/D,EAAA,MAAM,QAAQ,MAAO,CAAA,CAAA,EAAA,GAAA,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAS,UAAT,IAAkB,GAAA,EAAA,GAAA,EAAE,EAAE,WAAY,EAAA;AACvD,EAAI,IAAA,OAAA,CAAQ,UAAW,CAAA,aAAa,CAAK,IAAA,KAAA,CAAM,UAAW,CAAA,aAAa,CAAK,IAAA,KAAA,CAAM,UAAW,CAAA,aAAa,CAAG,EAAA;AAC3G,IAAO,OAAA,aAAA;AAAA;AAET,EAAO,OAAA,MAAA;AACT;AAeA,SAAS,kBAAkB,QAA6C,EAAA;AACtE,EAAA,MAAM,CAAI,GAAA,MAAA,CAAO,QAAY,IAAA,IAAA,GAAA,QAAA,GAAA,EAAE,EAAE,IAAK,EAAA;AACtC,EAAI,IAAA,CAAC,GAAU,OAAA,EAAA;AACf,EAAA,IAAI,sEAAuE,CAAA,IAAA,CAAK,CAAC,CAAA,EAAU,OAAA,EAAA;AAC3F,EAAO,OAAA,CAAA;AACT;AAoBO,SAAS,wBAAwB,OAAiD,EAAA;AA9RzF,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AA+RE,EAAA,MAAM,SAAY,GAAA,MAAA,CAAA,CAAO,EAAS,GAAA,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAA,EAAA,KAAT,YAAe,EAAE,CAAA;AAC1C,EAAI,IAAA,CAAC,WAAkB,OAAA,IAAA;AACvB,EAAM,MAAA,WAAA,GAAA,CAAc,EAAS,GAAA,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAA,WAAA,KAAT,IAAwB,GAAA,EAAA,GAAA,IAAA;AAC5C,EAAM,MAAA,eAAA,GAAkB,mBAAmB,WAAW,CAAA;AACtD,EAAM,MAAA,gBAAA,GAAmB,oBAAoB,WAAW,CAAA;AACxD,EAAM,MAAA,aAAA,GAAgB,iBAAiB,IAAK,EAAA;AAC5C,EAAM,MAAA,QAAA,GAAW,eAAoB,KAAA,MAAA,KAAU,WAAa,IAAA,IAAA,GAAA,MAAA,GAAA,WAAA,CAAA,OAAA,CAAA,GAAU,OAAO,WAAY,CAAA,OAAO,CAAE,CAAA,IAAA,EAAS,GAAA,EAAA;AAC3G,EAAM,MAAA,mBAAA,GAAsB,iBAAkB,CAAA,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAS,KAAK,CAAA;AAO5D,EAAM,MAAA,kBAAA,GAAqB,iBAAkB,CAAA,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAS,WAAW,CAAA;AACjE,EAAI,IAAA,aAAA,GAAgB,aAAiB,IAAA,QAAA,IAAY,mBAAuB,IAAA,kBAAA;AACxE,EAAA,MAAM,gBAAgB,CAAC,aAAA;AASvB,EAAA,IAAI,eAA+B,aAAA,GAAA,gBAAA;AACnC,EAAM,MAAA,UAAA,GAAa,MAAO,CAAA,CAAA,EAAA,GAAA,WAAA,IAAA,IAAA,GAAA,MAAA,GAAA,WAAA,CAAa,OAAb,KAAA,IAAA,GAAA,EAAA,GAAwB,EAAE,CAAA,CAAE,OAAQ,CAAA,MAAA,EAAQ,GAAG,CAAA,CAAE,IAAK,EAAA;AAChF,EAAA,IAAI,OAAU,GAAA,UAAA;AACd,EAAI,IAAA,OAAA,IAAW,OAAY,KAAA,aAAA,EAAyB,OAAA,GAAA,EAAA;AACpD,EAAA,MAAM,UAAU,MAAM;AACpB,IAAM,MAAA,UAAA,GAAa,CAAC,OAAS,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAA,SAAA,EAAW,2CAAa,SAAW,EAAA,WAAA,IAAA,IAAA,GAAA,MAAA,GAAA,WAAA,CAAa,SAAW,EAAA,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAS,SAAS,CAAA;AAC1G,IAAA,KAAA,MAAW,aAAa,UAAY,EAAA;AAClC,MAAA,IAAI,SAAW,EAAA;AACb,QAAA,MAAM,CAAI,GAAA,IAAI,IAAK,CAAA,SAAS,EAAE,OAAQ,EAAA;AACtC,QAAA,IAAI,OAAO,QAAS,CAAA,CAAC,CAAK,IAAA,CAAA,GAAI,GAAU,OAAA,CAAA;AAAA;AAC1C;AAEF,IAAA,OAAO,KAAK,GAAI,EAAA;AAAA,GACf,GAAA;AACH,EAAM,MAAA,YAAA,GAAA,CAAe,mCAAS,SAAY,IAAA,IAAI,KAAK,OAAQ,CAAA,SAAS,CAAE,CAAA,OAAA,EAAY,GAAA,MAAA;AAClF,EAAO,OAAA;AAAA,IACL,SAAA;AAAA,IACA,KAAO,EAAA,aAAA;AAAA,IACP,OAAA;AAAA,IACA,IAAA,EAAM,WAAW,OAAO,CAAA;AAAA,IACxB,SAAA,EAAW,IAAI,IAAA,CAAK,MAAM,CAAA;AAAA,IAC1B,SAAA,EAAW,IAAI,IAAK,CAAA,MAAA,CAAO,SAAS,YAAY,CAAA,GAAI,eAAe,MAAM,CAAA;AAAA,IACzE;AAAA,GACF;AACF;AAGO,SAAS,gCAAgC,IAEJ,EAAA;AArV5C,EAAA,IAAA,EAAA;AAsVE,EAAA,MAAM,QAAY,GAAA,CAAA,EAAA,GAAA,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAM,cAAN,KAAA,IAAA,GAAA,EAAA,GAAwB,EAAC;AAC3C,EAAA,OAAO,SAAS,MAAO,CAAA,CAAC,CAAwB,KAAA,OAAA,CAAQ,uBAAG,EAAE,CAAA,KAAM,EAAC,CAAA,IAAA,IAAA,GAAA,MAAA,GAAA,CAAA,CAAG,SAAQ,CAAE,CAAA,IAAA,KAAS,SAAS,WAAY,CAAA,CAAA,CAAE,IAAI,CAAK,CAAA,KAAA,uBAAA,CAAwB,CAAC,CAAC,EAAE,MAAO,CAAA,CAAC,QAAmC,GAAQ,KAAA,IAAI,EAAE,IAAK,CAAA,CAAC,CAAG,EAAA,CAAA,KAAM,EAAE,SAAU,CAAA,OAAA,KAAY,CAAE,CAAA,SAAA,CAAU,SAAS,CAAA;AAC7Q;AAegB,SAAA,kCAAA,CAAmC,SAAoC,OAEpF,EAAA;AAzWH,EAAA,IAAA,EAAA,EAAA,EAAA;AA0WE,EAAM,MAAA,IAAA,GAAA,CAAO,OAAS,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAA,IAAA,KAAQ,CAAC,OAAA;AAC/B,EAAM,MAAA,SAAA,GAAY,QAAQ,MAAM,gCAAA,CAAiC,OAAO,CAAG,EAAA,CAAC,OAAO,CAAC,CAAA;AACpF,EAAM,MAAA;AAAA,IACJ,IAAA;AAAA,IACA,OAAA;AAAA,IACA,KAAA;AAAA,IACA;AAAA,MACE,wCAAyC,CAAA;AAAA,IAC3C,SAAA;AAAA,IACA,IAAA;AAAA,IACA,WAAa,EAAA,mBAAA;AAAA,IACb,2BAA6B,EAAA,IAAA;AAAA,IAC7B,OAAS,EAAA;AAAA,MACP,QAAU,EAAA;AAAA;AACZ,GACD,CAAA;AACD,EAAM,MAAA,QAAA,GAAW,QAAQ,MAAM,+BAAA,CAAgC,IAAI,CAAG,EAAA,CAAC,IAAI,CAAC,CAAA;AAC5E,EAAA,MAAM,kBAAqB,GAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAM,cAAN,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAsB,WAAtB,IAAgC,GAAA,EAAA,GAAA,CAAA;AAO3D,EAAA,MAAM,iBAAiB,IAAS,KAAA,MAAA;AAChC,EAAO,OAAA;AAAA,IACL,QAAA;AAAA,IACA,OAAA;AAAA,IACA,cAAA;AAAA,IACA,KAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,GACF;AACF;AACA,SAAS,qBAAqB,OAAyB,EAAA;AACrD,EAAA,MAAM,UAAa,GAAA,OAAA,CAAQ,OAAQ,CAAA,OAAA,EAAS,IAAI,CAAA;AAChD,EAAO,OAAA,UAAA,CAAW,OAAQ,CAAA,uFAAA,EAAyF,EAAE,CAAA;AACvH;AACA,SAAS,8BAAA,CAA+B,MAAe,OAAyB,EAAA;AAC9E,EAAA,OAAO,IAAS,KAAA,WAAA,GAAc,oBAAqB,CAAA,OAAO,CAAI,GAAA,OAAA;AAChE;AACA,SAAS,YAA2C,KAAiD,EAAA;AACnG,EAAM,MAAA,KAAA,GAAQ,cACR,CAAA,EAAA,EAAA,KAAA,IAAA,IAAA,GAAA,KAAA,GAAS,EAAC,CAAA;AAEhB,EAAA,OAAO,KAAM,CAAA,OAAA;AACb,EAAO,OAAA,KAAA;AACT;AAyFA,SAAS,sBAAA,CAAuB,MAAmB,iBAA0C,EAAA;AAlf7F,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AAmfE,EAAA,MAAM,KAAS,GAAA,CAAA,EAAA,GAAA,IAAA,CAAK,KAAL,KAAA,IAAA,GAAA,EAAA,GAAc,EAAC;AAC9B,EAAA,MAAM,YAAW,EAAK,GAAA,CAAA,EAAA,GAAA,IAAA,CAAA,kBAAA,KAAL,IAAyB,GAAA,MAAA,GAAA,EAAA,CAAA,QAAA,KAAzB,YAAqC,EAAC;AACvD,EAAM,MAAA,OAAA,GAAA,CAAU,EAAM,GAAA,CAAA,EAAA,GAAA,KAAA,CAAA,IAAA,KAAN,IAAc,GAAA,EAAA,GAAA,QAAA,CAAS,IAAvB,KAAA,IAAA,GAAA,EAAA,GAAA,CAA+B,EAAK,GAAA,CAAA,EAAA,GAAA,IAAA,CAAA,kBAAA,KAAL,IAAyB,GAAA,MAAA,GAAA,EAAA,CAAA,OAAA,KAAzB,IAAkC,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA;AACjF,EAAA,IAAI,IAA8B,GAAA,WAAA;AAClC,EAAA,IAAI,OAAY,KAAA,MAAA,IAAU,OAAY,KAAA,kBAAA,CAAmB,MAAa,IAAA,GAAA,MAAA;AAAA,OAAA,IAAgB,OAAY,KAAA,WAAA,IAAe,OAAY,KAAA,kBAAA,CAAmB,WAAkB,IAAA,GAAA,WAAA;AAAA,OAAqB,IAAA,OAAA,KAAY,UAAiB,IAAA,GAAA,QAAA;AACpN,EAAM,MAAA,UAAA,GAAA,CAAa,EAAM,GAAA,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAA,OAAA,KAAN,IAAiB,GAAA,EAAA,GAAA,EAAA;AACpC,EAAM,MAAA,OAAA,GAAU,8BAA+B,CAAA,IAAA,EAAM,UAAU,CAAA;AAC/D,EAAO,OAAA;AAAA,IACL,EAAI,EAAA,CAAA,EAAA,GAAA,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAM,EAAN,KAAA,IAAA,GAAA,EAAA,GAAYA,EAAO,EAAA;AAAA,IACvB,SAAW,EAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAM,OAAN,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAe,OAAf,IAAqB,GAAA,EAAA,GAAA,iBAAA;AAAA,IAChC,IAAA;AAAA,IACA,OAAA;AAAA,IACA,WAAA,EAAA,CAAA,CAAc,wCAAM,KAAN,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAa,SAAb,IAAqB,GAAA,EAAA,GAAA,EAAI,EAAA,GAAA,CAAI,CAAK,IAAA,KAAA;AA/fpD,MAAAC,IAAAA,GAAAA,EAAAC,GAAAC,EAAAA,GAAAA,EAAAC,GAAAC,EAAAA,GAAAA;AA+fwD,MAAA,OAAA;AAAA,QAClD,KAAIJ,GAAA,GAAA,IAAA,CAAK,EAAL,KAAA,IAAA,GAAAA,MAAWD,EAAO,EAAA;AAAA,QACtB,IAAME,EAAAA,CAAAA,GAAAA,GAAA,IAAK,CAAA,IAAA,KAAL,OAAAA,GAAa,GAAA,MAAA;AAAA,QACnB,IAAA,EAAM,OAAO,IAAA,CAAK,QAAa,KAAA,QAAA,IAAY,KAAK,QAAS,CAAA,UAAA,CAAW,QAAQ,CAAA,GAAI,YAAe,GAAA,MAAA;AAAA,QAC/F,QAAUC,EAAAA,CAAAA,GAAAA,GAAA,IAAK,CAAA,QAAA,KAAL,OAAAA,GAAiB,GAAA,MAAA;AAAA,QAC3B,IAAMC,EAAAA,CAAAA,GAAAA,GAAA,IAAK,CAAA,IAAA,KAAL,OAAAA,GAAa,GAAA,MAAA;AAAA,QACnB,GAAKC,EAAAA,CAAAA,GAAAA,GAAA,IAAK,CAAA,GAAA,KAAL,OAAAA,GAAY,GAAA;AAAA,OACnB;AAAA,KAAE,CAAA;AAAA,IACF,UAAA,EAAA,CAAY,EAAM,GAAA,KAAA,CAAA,UAAA,KAAN,IAAoB,GAAA,EAAA,GAAA,MAAA;AAAA,IAChC,KAAA,EAAA,CAAO,EAAM,GAAA,KAAA,CAAA,KAAA,KAAN,IAAe,GAAA,EAAA,GAAA,MAAA;AAAA,IACtB,SAAA,EAAA,CAAW,6BAAM,SAAY,IAAA,IAAI,KAAK,IAAK,CAAA,SAAS,CAAI,mBAAA,IAAI,IAAK,EAAA;AAAA,IACjE,SAAA,EAAA,CAAW,6BAAM,SAAY,IAAA,IAAI,KAAK,IAAK,CAAA,SAAS,CAAI,mBAAA,IAAI,IAAK;AAAA,GACnE;AACF;AACgB,SAAA,eAAA,CAAgB,WAA0B,OAEvD,EAAA;AACD,EAAM,MAAA;AAAA,IACJ,IAAA;AAAA,IACA,OAAA;AAAA,IACA,KAAA;AAAA,IACA;AAAA,MACE,gBAAiB,CAAA;AAAA,IACnB,SAAW,EAAA;AAAA,MACT,WAAW,SAAa,IAAA,IAAA,GAAA,SAAA,GAAA,MAAA;AAAA,MACxB,QAAU,EAAA,IAAA;AAAA,MACV,KAAO,EAAA,mBAAA;AAAA,MACP,IAAM,EAAA;AAAA,KACR;AAAA,IACA,IAAA,EAAM,CAAC,SAAA,KAAsB,MAAA,CAAA,CAAA;AAAA,IAC7B,WAAa,EAAA,mBAAA;AAAA,IACb,2BAA6B,EAAA,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAM7B,OAAS,EAAA;AAAA,MACP,QAAU,EAAA,SAAA,GAAY,CAAiB,cAAA,EAAA,SAAS,CAAK,CAAA,GAAA;AAAA;AACvD,GACD,CAAA;AAWD,EAAA,MAAM,iBAAiB,IAAS,KAAA,MAAA;AAChC,EAAM,MAAA,QAAA,GAA4B,QAAQ,MAAM;AAnjBlD,IAAA,IAAA,EAAA,EAAA,EAAA;AAojBI,IAAI,IAAA,CAAC,SAAW,EAAA,OAAO,EAAC;AACxB,IAAA,MAAM,QAAO,EAAM,GAAA,CAAA,EAAA,GAAA,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAA,QAAA,KAAN,IAAgB,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,KAAhB,YAAwB,EAAC;AACtC,IAAA,OAAO,KAAK,GAAI,CAAA,CAAA,IAAA,KAAQ,uBAAuB,IAAqB,EAAA,SAAS,CAAC,CAAE,CAAA,IAAA,CAAK,CAAC,CAAG,EAAA,CAAA,KAAM,EAAE,SAAU,CAAA,OAAA,KAAY,CAAE,CAAA,SAAA,CAAU,SAAS,CAAA;AAAA,GAC3I,EAAA,CAAC,IAAM,EAAA,SAAS,CAAC,CAAA;AACpB,EAAO,OAAA;AAAA,IACL,QAAA;AAAA,IACA,OAAA;AAAA,IACA,cAAA;AAAA,IACA,KAAA;AAAA,IACA;AAAA,GACF;AACF;AAOA,SAAS,qBAAqB,KAAyB,EAAA;AAtkBvD,EAAA,IAAA,EAAA;AAukBE,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,IAAI,KAAS,IAAA,OAAO,KAAU,KAAA,QAAA,IAAY,mBAAmB,KAAO,EAAA;AAClE,IAAA,MAAM,SAAa,GAAA,CAAA,EAAA,GAAA,KAAA,CAIhB,aAJgB,KAAA,IAAA,GAAA,EAAA,GAIC,EAAC;AACrB,IAAA,KAAA,CAAM,IAAK,CAAA,GAAG,SAAU,CAAA,GAAA,CAAI,CAAE,CAAA,KAAA;AA9kBlC,MAAAJ,IAAAA,GAAAA;AA8kBqC,MAAA,OAAA,CAAAA,GAAA,GAAA,CAAA,IAAA,IAAA,GAAA,MAAA,GAAA,CAAA,CAAG,OAAH,KAAA,IAAA,GAAAA,GAAc,GAAA,EAAA;AAAA,KAAE,CAAC,CAAA;AAAA;AAEpD,EAAA,IAAI,iBAAiB,KAAO,EAAA;AAC1B,IAAM,KAAA,CAAA,IAAA,CAAK,MAAM,OAAO,CAAA;AAAA,GAC1B,MAAA,IAAW,SAAS,IAAM,EAAA;AACxB,IAAM,KAAA,CAAA,IAAA,CAAK,MAAO,CAAA,KAAK,CAAC,CAAA;AAAA;AAE1B,EAAM,MAAA,GAAA,GAAM,KAAM,CAAA,IAAA,CAAK,GAAG,CAAA;AAC1B,EAAO,OAAA,uBAAA,CAAwB,KAAK,GAAG,CAAA;AACzC;AACO,SAAS,gBAAmB,GAAA;AACjC,EAAA,MAAM,CAAC,kBAAoB,EAAA;AAAA,IACzB,OAAS,EAAA;AAAA,GACV,IAAI,qBAAsB,EAAA;AAC3B,EAAA,MAAM,CAAC,oBAAsB,EAAA;AAAA,IAC3B,OAAS,EAAA;AAAA,GACV,IAAI,uBAAwB,EAAA;AAC7B,EAAM,MAAA,aAAA,GAAgB,WAAY,CAAA,OAAO,KAAmE,KAAA;AA/lB9G,IAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AAgmBI,IAIK,MAAA,EAAA,GAAA,KAAA,IAAA,IAAA,GAAA,KAAA,GAAS,EAHZ,EAAA;AAAA,MAAS,OAAA,EAAA,UAAA;AAAA,MACT,SAAW,EAAA;AAAA,KAlmBjB,GAomBS,EADA,EAAA,gBAAA,GAAA,SAAA,CACA,EADA,EAAA;AAAA,MAFH,SAAA;AAAA,MACA;AAAA,KAAA,CAAA;AAMF,IAAM,MAAA,OAAA,GAAU,OAAO,UAAA,KAAe,QAAY,IAAA,UAAA,CAAW,IAAK,EAAA,CAAE,MAAS,GAAA,CAAA,GAAI,UAAW,CAAA,IAAA,EAAS,GAAA,MAAA;AACrG,IAAM,MAAA,SAAA,GAAY,OAAO,YAAA,KAAiB,QAAY,IAAA,YAAA,CAAa,IAAK,EAAA,CAAE,MAAS,GAAA,CAAA,GAAI,YAAa,CAAA,IAAA,EAAS,GAAA,MAAA;AAC7G,IAAA,MAAM,QAAW,GAAA,cAAA,CAAA;AAAA,MACf,KAAA,EAAA,CAAO,EAAO,GAAA,KAAA,IAAA,IAAA,GAAA,MAAA,GAAA,KAAA,CAAA,KAAA,KAAP,IAAgB,GAAA,EAAA,GAAA,UAAA;AAAA,MACvB,WAAA,EAAA,CAAa,EAAO,GAAA,KAAA,IAAA,IAAA,GAAA,MAAA,GAAA,KAAA,CAAA,YAAA,KAAP,IAAuB,GAAA,EAAA,GAAA,IAAA;AAAA,MACpC,QAAU,EAAA,KAAA;AAAA,MACV,UAAY,EAAA,IAAA;AAAA,MACZ,UAAY,EAAA,KAAA;AAAA,MACZ,QAAU,EAAA,KAAA;AAAA,MACV,KAAA,EAAA,CAAO,EAAO,GAAA,KAAA,IAAA,IAAA,GAAA,MAAA,GAAA,KAAA,CAAA,KAAA,KAAP,IAAgB,GAAA,EAAA,GAAA,IAAA;AAAA,MACvB,YAAA,EAAA,CAAc,EAAO,GAAA,KAAA,IAAA,IAAA,GAAA,MAAA,GAAA,KAAA,CAAA,YAAA,KAAP,IAAuB,GAAA,EAAA,GAAA;AAAA,KAClC,EAAA,gBAAA,CAAA;AAEL,IAAM,MAAA;AAAA,MACJ;AAAA,KACF,GAAI,MAAM,kBAAmB,CAAA;AAAA,MAC3B,SAAW,EAAA,cAAA,CAAA,cAAA,CAAA;AAAA,QACT,SAAA,EAAA,CAAW,EAAO,GAAA,KAAA,IAAA,IAAA,GAAA,MAAA,GAAA,KAAA,CAAA,EAAA,KAAP,IAAa,GAAA,EAAA,GAAA,IAAA;AAAA,QACxB,IAAA,EAAA,CAAM,EAAO,GAAA,KAAA,IAAA,IAAA,GAAA,MAAA,GAAA,KAAA,CAAA,KAAA,KAAP,IAAgB,GAAA,EAAA,GAAA,UAAA;AAAA,QACtB,WAAA,EAAA,CAAa,EAAO,GAAA,KAAA,IAAA,IAAA,GAAA,MAAA,GAAA,KAAA,CAAA,YAAA,KAAP,IAAuB,GAAA,EAAA,GAAA,IAAA;AAAA,QACpC,MAAM,QAAS,CAAA,WAAA;AAAA,QACf;AAAA,OAAA,EACI,OAAU,GAAA;AAAA,QACZ;AAAA,OACF,GAAI,EAAC,CAAA,EACD,SAAY,GAAA;AAAA,QACd;AAAA,UACE,EAAC,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAcP,gBAAgB,CAAC;AAAA,QACf,KAAO,EAAA,wCAAA;AAAA,QACP,SAAW,EAAA;AAAA,OACb,EAAG,GAAI,OAAA,GAAU,CAAC;AAAA,QAChB,KAAO,EAAA,wCAAA;AAAA,QACP,SAAA,EAAW,iCAAiC,OAAO;AAAA,OACpD,CAAI,GAAA,EAAK,EAAA;AAAA,QACR,KAAO,EAAA,wCAAA;AAAA,QACP,SAAW,EAAA;AAAA,OACZ,CAAA;AAAA,MACD,mBAAqB,EAAA;AAAA,KACtB,CAAA;AACD,IAAA,IAAI,EAAC,CAAA,EAAA,GAAA,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAM,aAAN,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAqB,EAAI,CAAA,EAAA;AAC5B,MAAM,MAAA,IAAI,MAAM,0BAA0B,CAAA;AAAA;AAE5C,IAAA,MAAM,UAAU,IAAK,CAAA,aAAA;AACrB,IAAA,MAAM,SAAQ,EAAQ,GAAA,CAAA,EAAA,GAAA,OAAA,CAAA,KAAA,KAAR,IAAiB,GAAA,EAAA,GAAA,KAAA,IAAA,IAAA,GAAA,MAAA,GAAA,KAAA,CAAO,UAAxB,IAAiC,GAAA,EAAA,GAAA,UAAA;AAC/C,IAAM,MAAA,GAAA,uBAAU,IAAK,EAAA;AACrB,IAAO,OAAA;AAAA,MACL,IAAI,OAAQ,CAAA,EAAA;AAAA,MACZ,KAAA;AAAA,MACA,SAAW,EAAA,GAAA;AAAA,MACX,SAAW,EAAA;AAAA,KACb;AAAA,GACF,EAAG,CAAC,kBAAkB,CAAC,CAAA;AACvB,EAAM,MAAA,YAAA,GAAe,WAAY,CAAA,OAAO,KAIlC,KAAA;AA9qBR,IAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AA+qBI,IAAA,MAAM,4BAA4B,oBAAqB,CAAA,CAAA,EAAA,GAAA,KAAA,CAAM,gBAAiB,CAAA,OAAA,KAAvB,YAAkC,EAAE,CAAA;AAC3F,IAAA,MAAM,iCAAiC,WAAY,CAAA,CAAA,EAAA,GAAA,KAAA,CAAM,gBAAN,KAAA,IAAA,GAAA,EAAA,GAAiC,EAAE,CAAA;AACtF,IAAI,IAAA,QAAA;AACJ,IAAI,IAAA;AACF,MAAM,MAAA,UAAA,GAAa,MAAM,oBAAqB,CAAA;AAAA,QAC5C,SAAW,EAAA,aAAA,CAAA,cAAA,CAAA;AAAA,UACT,WAAW,KAAM,CAAA,SAAA;AAAA,UACjB,MAAM,QAAS,CAAA,WAAA;AAAA,UACf,OAAS,EAAA,CAAA,EAAA,GAAA,KAAA,CAAM,WAAY,CAAA,OAAA,KAAlB,IAA6B,GAAA,EAAA,GAAA;AAAA,SAAA,EAClC,MAAM,SAAY,GAAA;AAAA,UACpB,WAAW,KAAM,CAAA;AAAA,SACnB,GAAI,EANK,CAAA,EAAA;AAAA,UAOT,UAAY,EAAA,cAAA,CAAA,cAAA,CAAA;AAAA,YACV,MAAM,YAAa,CAAA,WAAA;AAAA,YACnB,IAAM,EAAA,MAAA;AAAA,YACN,WAAa,EAAA,CAAA,EAAA,GAAA,KAAA,CAAM,WAAY,CAAA,WAAA,KAAlB,YAAiC,EAAC;AAAA,YAC/C,QAAU,EAAA,IAAA;AAAA,YACV,MAAQ,EAAA;AAAA,WACJ,EAAA,KAAA,CAAM,WACN,CAAA,EAAA,KAAA,CAAM,IAAO,GAAA;AAAA,YACf,MAAM,KAAM,CAAA;AAAA,cACV,EAAC;AAAA,SAET;AAAA,OACD,CAAA;AACD,MAAW,QAAA,GAAA,CAAA,EAAA,GAAA,UAAA,CAAW,SAAX,IAAiB,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,WAAA;AAAA,aACrB,GAAK,EAAA;AACZ,MAAI,IAAA,CAAC,oBAAqB,CAAA,GAAG,CAAG,EAAA;AAC9B,QAAM,MAAA,GAAA;AAAA;AAER,MAAA,OAAA,CAAQ,KAAK,wEAAwE,CAAA;AAAA;AAQvF,IAAM,MAAA,UAAA,GAAA,CAAa,EAAU,GAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAA,EAAA,KAAV,IAAgB,GAAA,EAAA,GAAA,IAAA;AACnC,IAAI,IAAA,aAAA;AACJ,IAAI,IAAA;AACF,MAAM,MAAA,eAAA,GAAkB,MAAM,oBAAqB,CAAA;AAAA,QACjD,SAAW,EAAA;AAAA,UACT,WAAW,KAAM,CAAA,SAAA;AAAA,UACjB,MAAM,QAAS,CAAA,WAAA;AAAA,UACf,OAAS,EAAA,yBAAA;AAAA,UACT,UAAY,EAAA,cAAA,CAAA,cAAA,CAAA,cAAA,CAAA;AAAA,YACV,MAAM,YAAa,CAAA,WAAA;AAAA,YACnB,IAAM,EAAA,WAAA;AAAA,YACN,WAAa,EAAA,CAAA,EAAA,GAAA,KAAA,CAAM,gBAAiB,CAAA,WAAA,KAAvB,YAAsC,EAAC;AAAA,YACpD,UAAA,EAAY,MAAM,gBAAiB,CAAA,UAAA;AAAA,YACnC,SAAA,EAAW,MAAM,gBAAiB,CAAA,SAAA;AAAA,YAClC,KAAA,EAAO,MAAM,gBAAiB,CAAA,KAAA;AAAA,YAC9B,YAAe,EAAA,CAAA,EAAA,GAAA,KAAA,CAAM,gBAAyB,CAAA,YAAA,KAA/B,IAA+C,GAAA,EAAA,GAAA,IAAA;AAAA,YAC9D,QAAU,EAAA,IAAA;AAAA,YACV,MAAQ,EAAA;AAAA,WAAA,EACL,iCACC,UAAa,GAAA;AAAA,YACf,QAAU,EAAA;AAAA,WACR,GAAA,EACA,CAAA,EAAA,KAAA,CAAM,IAAO,GAAA;AAAA,YACf,MAAM,KAAM,CAAA;AAAA,cACV,EAAC;AAAA;AAET,OACD,CAAA;AACD,MAAgB,aAAA,GAAA,CAAA,EAAA,GAAA,eAAA,CAAgB,SAAhB,IAAsB,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,WAAA;AAAA,aAC/B,GAAK,EAAA;AACZ,MAAI,IAAA,CAAC,oBAAqB,CAAA,GAAG,CAAG,EAAA;AAC9B,QAAM,MAAA,GAAA;AAAA;AAER,MAAA,OAAA,CAAQ,KAAK,6EAA6E,CAAA;AAAA;AAE5F,IAAI,IAAA,CAAC,QAAY,IAAA,CAAC,aAAe,EAAA;AAC/B,MAAM,MAAA,IAAI,MAAM,yBAAyB,CAAA;AAAA;AAE3C,IAAM,MAAA,GAAA,uBAAU,IAAK,EAAA;AACrB,IAAA,MAAM,YAA8B,GAAA;AAAA,MAClC,EAAA,EAAI,kCAAcD,EAAO,EAAA;AAAA,MACzB,WAAW,KAAM,CAAA,SAAA;AAAA,MACjB,IAAM,EAAA,MAAA;AAAA,MACN,OAAS,EAAA,CAAA,EAAA,GAAA,KAAA,CAAM,WAAY,CAAA,OAAA,KAAlB,IAA6B,GAAA,EAAA,GAAA,EAAA;AAAA,MACtC,SAAW,EAAA,GAAA;AAAA,MACX,SAAW,EAAA;AAAA,KACb;AACA,IAAA,MAAM,iBAAmC,GAAA;AAAA,MACvC,IAAIA,EAAO,EAAA;AAAA,MACX,WAAW,KAAM,CAAA,SAAA;AAAA,MACjB,IAAM,EAAA,WAAA;AAAA,MACN,OAAS,EAAA,yBAAA;AAAA,MACT,SAAW,EAAA,GAAA;AAAA,MACX,SAAW,EAAA,GAAA;AAAA,MACX,UAAA,EAAY,MAAM,gBAAiB,CAAA,UAAA;AAAA,MACnC,KAAA,EAAO,MAAM,gBAAiB,CAAA;AAAA,KAChC;AACA,IAAO,OAAA;AAAA,MACL,aAAa,QAAW,GAAA,sBAAA,CAAuB,QAAU,EAAA,KAAA,CAAM,SAAS,CAAI,GAAA,YAAA;AAAA,MAC5E,kBAAkB,aAAgB,GAAA,sBAAA,CAAuB,aAAe,EAAA,KAAA,CAAM,SAAS,CAAI,GAAA,iBAAA;AAAA,MAC3F,OAAS,EAAA;AAAA,QACP,IAAI,KAAM,CAAA,SAAA;AAAA,QACV,KAAO,EAAA,MAAA;AAAA,QACP,SAAW,EAAA,GAAA;AAAA,QACX,SAAW,EAAA;AAAA;AACb,KACF;AAAA,GACF,EAAG,CAAC,oBAAoB,CAAC,CAAA;AACzB,EAAO,OAAA;AAAA,IACL,aAAA;AAAA,IACA,aAAe,EAAA,aAAA;AAAA,IACf,YAAA;AAAA,IACA,OAAS,EAAA;AAAA,MACP,MAAQ,EAAA,oBAAA;AAAA,MACR,YAAc,EAAA;AAAA;AAChB,GACF;AACF"}
|
|
1
|
+
{"version":3,"file":"useChatApi.js","sources":["../../src/hooks/useChatApi.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { AiAgentMessageRole, PostTypeEnum, RoomType, SortEnum } from 'common';\nimport {\n GetChannelsByUserWithLastMessageDocument,\n useAddChannelMutation,\n useGetChannelsByUserWithLastMessageQuery,\n useMessagesQuery,\n useSendMessagesMutation,\n} from 'common/graphql';\nimport type {\n IAccountCreateChatSessionInput,\n IAccountSaveChatMessagesInput as IAccountSaveChatMessagesInputBase,\n} from 'common/server';\nimport { useCallback, useMemo } from 'react';\nimport { v4 as uuidv4 } from 'uuid';\n\nconst MESSAGES_PAGE_LIMIT = 100;\n\n/** Same variables as web Inbox / AIAgent: list AI assistant channels for the current user. */\nexport const AI_ASSISTANT_CHANNELS_QUERY_VARS = {\n criteria: { type: RoomType.Aiassistant },\n limit: 100,\n skip: 0,\n sort: { key: 'updatedAt', value: SortEnum.Desc },\n};\n\nexport const HISTORY_PAGE_SIZE = 20;\n\n/**\n * Variables for the channels-based chat history list (`ChatHistoryLanding`).\n *\n * IMPORTANT: pass the user's org `slug` (e.g. `tarun-upadhyay-qraw`) so the\n * `channelsByUser` resolver's `$in: [criteria.orgName, orgId]` includes\n * channels stored under the slug. When `criteria.orgName` is omitted, the\n * `$in` collapses to just `[orgId]` and channels saved with the slug as\n * `orgName` (the mobile create path) never match. That's the cause of the\n * silently-empty history screen.\n *\n * Kept as a builder (not a constant) because the slug varies per user and\n * because Apollo treats different `variables` as different cached entries —\n * if the create mutation refetches a no-orgName variant, the orgName-variant\n * the screen watches stays stale.\n */\nexport function getHistoryChannelsQueryVariables(orgName?: string | null, options?: { skip?: number; limit?: number }) {\n const trimmedOrg = typeof orgName === 'string' && orgName.trim().length > 0 ? orgName.trim() : undefined;\n return {\n criteria: {\n type: RoomType.Aiassistant,\n ...(trimmedOrg ? { orgName: trimmedOrg } : {}),\n },\n limit: options?.limit ?? HISTORY_PAGE_SIZE,\n skip: options?.skip ?? 0,\n sort: { key: 'updatedAt' as const, value: SortEnum.Desc },\n };\n}\n\n/** @deprecated Use {@link getHistoryChannelsQueryVariables} so `orgName` is included. */\nexport const HISTORY_QUERY_BASE = getHistoryChannelsQueryVariables();\n\n/**\n * Variables for the chat-history feed on the mobile `ChatHistory` screen.\n *\n * First page uses `HISTORY_PAGE_SIZE` (20) posts; \"Load older\" paginates by post\n * `skip` in increments of 20. Rows are still one per channel (collapsed from posts).\n *\n * This query intentionally hits `messages` (not `channelsByUser`) — the same\n * pattern the web sidebar uses (`useNewChatPageHistorySessions`). Reasons:\n * 1. `channelsByUser` is server-side gated by an injected `orgName` /\n * `members` filter that can mismatch when channels were stored with an\n * org slug while the resolver injects the org id. The `messages`\n * resolver filters Post directly by `editedBy: accountId`, so the\n * user's own AI-assistant posts always show up.\n * 2. The user-authored post IS the conversation's natural title — no need\n * to walk `lastMessage.propsConfiguration.contents.parent` to recover\n * the original prompt.\n *\n * - `type: AIASSISTANT` scopes to AI chat (not direct/service rooms).\n * - `props.role: 'user'` selects only the user's turns. The assistant reply\n * is ignored here; it would override the title with the agent's words.\n * - `editedBy: accountUserId` scopes to the current user's own posts,\n * independent of channel membership / org name.\n */\nexport function getChatHistoryMessagesQueryVariables(\n accountUserId: string,\n options?: { skip?: number; limit?: number },\n) {\n return {\n limit: options?.limit ?? HISTORY_PAGE_SIZE,\n skip: options?.skip ?? 0,\n sort: { key: 'updatedAt' as const, value: SortEnum.Desc },\n type: PostTypeEnum.Aiassistant,\n editedBy: accountUserId,\n props: { role: 'user' },\n };\n}\n\nexport type ChatHistoryMode = 'chat' | 'deep-search';\n\nexport interface ChatHistorySession {\n /** Channel id — used to navigate to the Chat screen. */\n channelId: string;\n /** User's most recent prompt in this channel (used as the row title). */\n title: string;\n /** Second line: latest post `message` field (same as Manus subtitle). */\n preview: string;\n /** Conversation mode (chat / deep-search), inferred from channel display name / title. */\n mode: ChatHistoryMode;\n /** Most-recent activity timestamp (sort key + bucket key for Today/Yesterday/…). */\n updatedAt: Date;\n createdAt: Date;\n /**\n * True when no concrete prompt was recoverable (no parent, no user turn, no\n * meaningful channel.title). UI renders the title in a quieter style.\n */\n isPlaceholder: boolean;\n}\n\n/**\n * Collapse a list of user-authored AI assistant posts (newest first) into one\n * row per channel. First post per `channel.id` wins the title, which — because\n * the query is sorted by `updatedAt DESC` — is the user's latest prompt in\n * that channel. Posts whose `channel.id` is missing (unexpected, but possible\n * if the resolver omits the relation) are skipped.\n */\nexport function chatHistorySessionsFromMessages(\n data: { messages?: { data?: unknown[] | null } | null } | null | undefined,\n): ChatHistorySession[] {\n const rows = data?.messages?.data;\n if (!rows?.length) return [];\n\n const seen = new Set<string>();\n const sessions: ChatHistorySession[] = [];\n\n for (const post of rows as any[]) {\n const channelId = post?.channel?.id ? String(post.channel.id) : '';\n if (channelId && !seen.has(channelId)) {\n seen.add(channelId);\n\n const rawTitle = String(post?.message ?? '')\n .replace(/\\s+/g, ' ')\n .trim();\n const updatedAt = post?.updatedAt ? new Date(post.updatedAt) : new Date();\n const createdAt = post?.createdAt ? new Date(post.createdAt) : updatedAt;\n const title = rawTitle || 'New chat';\n\n sessions.push({\n channelId,\n title,\n preview: '',\n mode: 'chat',\n updatedAt,\n createdAt,\n isPlaceholder: !rawTitle,\n });\n }\n }\n\n return sessions;\n}\n\n/**\n * Mobile parity hook for the web sidebar's `useNewChatPageHistorySessions`.\n *\n * Returns one row per channel where the user has authored at least one AI assistant\n * post, with the title taken from that user's latest prompt. Skipped when\n * `accountUserId` isn't known yet (we don't want to fire a query without it).\n */\nexport function useChatHistorySessionsFromMessages(\n accountUserId: string | null | undefined,\n options?: { skip?: boolean },\n) {\n const skip = options?.skip || !accountUserId;\n const { data, loading, error, refetch } = useMessagesQuery({\n variables: accountUserId ? getChatHistoryMessagesQueryVariables(accountUserId) : undefined,\n skip,\n fetchPolicy: 'cache-and-network',\n notifyOnNetworkStatusChange: true,\n context: { cacheKey: 'new-chat-history-messages' },\n });\n\n const sessions = useMemo(() => chatHistorySessionsFromMessages(data), [data]);\n const sourcePostCount = data?.messages?.data?.length ?? 0;\n\n return { sessions, loading, error, refetch, sourcePostCount };\n}\n\n/* -------------------------------------------------------------------------- */\n/* Channels-based chat history (parent + lastMessage) */\n/* -------------------------------------------------------------------------- */\n\ninterface ChannelLastMessageLike {\n message?: string | null;\n createdAt?: string | null;\n updatedAt?: string | null;\n props?: { role?: string | null } | null;\n propsConfiguration?: {\n contents?: {\n role?: string | null;\n parent?: {\n message?: string | null;\n props?: { role?: string | null } | null;\n } | null;\n } | null;\n content?: { role?: string | null } | null;\n } | null;\n}\n\ninterface ChannelLike {\n id?: string | null;\n type?: string | null;\n displayName?: string | null;\n title?: string | null;\n createdAt?: string | null;\n updatedAt?: string | null;\n lastMessage?: ChannelLastMessageLike | null;\n}\n\nfunction getLastMessageRole(lastMessage: ChannelLastMessageLike | null | undefined): string {\n return String(\n lastMessage?.propsConfiguration?.contents?.role ??\n lastMessage?.propsConfiguration?.content?.role ??\n lastMessage?.props?.role ??\n '',\n ).toUpperCase();\n}\n\nfunction getParentUserPrompt(lastMessage: ChannelLastMessageLike | null | undefined): string {\n const parent = lastMessage?.propsConfiguration?.contents?.parent;\n if (!parent) return '';\n return String(parent?.message ?? '').trim();\n}\n\nfunction detectMode(channel: ChannelLike): ChatHistoryMode {\n const display = String(channel?.displayName ?? '').toLowerCase();\n const title = String(channel?.title ?? '').toLowerCase();\n if (display.startsWith('deep-search') || title.startsWith('deep search') || title.startsWith('deep-search')) {\n return 'deep-search';\n }\n return 'chat';\n}\n\n/**\n * Drop the internal slug we use as `channel.title` for server-side mode detection\n * (`chat-channel-<uuid>` / `deep-search-<uuid>`) so it doesn't leak into the row\n * label. The server sometimes also reformats this slug into `displayName` as\n * title-cased text with spaces (e.g. `\"Deep Search b64be4f7 9fe6 …\"`) — those\n * are equally machine-generated and must NOT be shown to the user.\n *\n * Pattern accepts:\n * • `deep-search-<uuid>` / `chat-channel-<uuid>` (raw, mode signal)\n * • `Deep Search <uuid>` / `Chat Channel <uuid>` (display-cased, server-reformatted)\n * • UUID may use hyphens, spaces, or be partially truncated as long as the\n * trailing chunk is hex.\n */\nfunction cleanChannelTitle(rawTitle: string | null | undefined): string {\n const t = String(rawTitle ?? '').trim();\n if (!t) return '';\n if (/^(chat[\\s-]channel|deep[\\s-]search)[\\s-][0-9a-f][0-9a-f\\s-]{7,}\\.?$/i.test(t)) return '';\n // Creation defaults carry no meaning either (parity with the browser sidebar).\n if (/^(new chat|workflow|deep search)$/i.test(t)) return '';\n return t;\n}\n\n/** `[Active connectors: …]` routing prefix on persisted gateway user posts. */\nconst ACTIVE_CONNECTORS_PREFIX_RE = /^\\s*\\[Active connectors:[^\\]]*\\]\\s*/i;\n\nfunction cleanMessageText(raw: string): string {\n return raw.replace(ACTIVE_CONNECTORS_PREFIX_RE, '').trim();\n}\n\n/**\n * Map one channel into a session row (Manus-style two-line list):\n *\n * **Title (line 1):** `lastMessage.propsConfiguration.contents.parent.message`\n * when present (the user turn the thread is anchored on). Otherwise fall back\n * to the last post body if that post is still a user message, then a\n * machine-slug-stripped channel title, then a machine-slug-stripped\n * `displayName`, then `\"Thinking…\"`. Machine slugs (`deep-search-<uuid>`,\n * `chat-channel-<uuid>`, and their server-reformatted display variants)\n * are filtered via `cleanChannelTitle`, so they never reach the row.\n *\n * **Preview (line 2):** `lastMessage.message` as returned by the API (trimmed,\n * whitespace collapsed). Agent errors that start with `⚠` stay visible in the\n * subtitle, matching the reference UI.\n *\n * If preview text equals the title after trim, the second line is omitted\n * (single-line channel, no duplicate).\n */\nexport function buildSessionFromChannel(channel: ChannelLike): ChatHistorySession | null {\n const channelId = String(channel?.id ?? '');\n if (!channelId) return null;\n\n const lastMessage = channel?.lastMessage ?? null;\n const lastMessageRole = getLastMessageRole(lastMessage);\n const parentUserPrompt = getParentUserPrompt(lastMessage);\n const parentTrimmed = cleanMessageText(parentUserPrompt);\n\n const userTurn =\n lastMessageRole === 'USER' && lastMessage?.message ? cleanMessageText(String(lastMessage.message)) : '';\n const cleanedChannelTitle = cleanChannelTitle(channel?.title);\n /**\n * Apply the same machine-slug cleaner to `displayName`. The server\n * sometimes derives displayName from the title (`\"deep-search-<uuid>\"`\n * → `\"Deep Search <uuid>\"`), so without this the slug bypasses\n * `cleanedChannelTitle` and lands directly in the row label.\n */\n const cleanedDisplayName = cleanChannelTitle(channel?.displayName);\n\n // A real channel title (brain headline / first-message name set at creation)\n // wins over raw message text — parity with the browser sidebar.\n let resolvedTitle = cleanedChannelTitle || parentTrimmed || userTurn || cleanedDisplayName;\n if (!resolvedTitle) {\n // Message-less channels with a friendly default show it instead of the\n // in-progress placeholder.\n const rawDefault = String(channel?.title ?? '').trim();\n if (rawDefault && !/^(chat[\\s-]channel|deep[\\s-]search)[\\s-][0-9a-f][0-9a-f\\s-]{7,}\\.?$/i.test(rawDefault)) {\n resolvedTitle = rawDefault;\n }\n }\n const isPlaceholder = !resolvedTitle;\n /**\n * When every signal fails — typical when a send just landed and the\n * server hasn't yet persisted the message that would populate\n * `propsConfiguration.contents.parent.message` — show `\"Thinking…\"`\n * instead of an empty label or the raw machine slug. The row's mode\n * tile still signals chat vs deep-search, so the user has enough\n * context to recognize the entry without leaking implementation noise.\n */\n if (isPlaceholder) resolvedTitle = 'Thinking…';\n\n const rawPreview = String(lastMessage?.message ?? '')\n .replace(/\\s+/g, ' ')\n .trim();\n let preview = rawPreview;\n if (preview && preview === parentTrimmed) preview = '';\n\n const sortAt = (() => {\n const candidates = [channel?.updatedAt, lastMessage?.updatedAt, lastMessage?.createdAt, channel?.createdAt];\n for (const candidate of candidates) {\n if (candidate) {\n const t = new Date(candidate).getTime();\n if (Number.isFinite(t) && t > 0) return t;\n }\n }\n return Date.now();\n })();\n\n const createdAtRaw = channel?.createdAt ? new Date(channel.createdAt).getTime() : sortAt;\n\n return {\n channelId,\n title: resolvedTitle,\n preview,\n mode: detectMode(channel),\n updatedAt: new Date(sortAt),\n createdAt: new Date(Number.isFinite(createdAtRaw) ? createdAtRaw : sortAt),\n isPlaceholder,\n };\n}\n\n/** Collapse a `channelsByUser` response into session rows for the history list. */\nexport function chatHistorySessionsFromChannels(\n data: { channelsByUser?: (ChannelLike | null)[] | null } | null | undefined,\n): ChatHistorySession[] {\n const channels = (data?.channelsByUser ?? []) as (ChannelLike | null)[];\n return channels\n .filter((c): c is ChannelLike => Boolean(c?.id) && (!c?.type || c.type === RoomType.Aiassistant))\n .map((c) => buildSessionFromChannel(c))\n .filter((row): row is ChatHistorySession => row !== null)\n .sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime());\n}\n\n/**\n * Chat history feed driven by `channelsByUser`. Each row: parent prompt as title,\n * `lastMessage.message` as subtitle (Manus-style), when the API provides them.\n *\n * Caller MUST pass `orgName` (the org slug). Without it, the resolver only\n * matches channels whose `orgName` field equals the user's `orgId`, which is\n * never the case for mobile-created channels (those store the slug). The hook\n * suspends the query (`skip: true`) until `orgName` is known, so we never\n * fire a guaranteed-empty request.\n *\n * Pagination is by channel count (one channel = one row in this query),\n * unlike the messages-based path which paginates by raw post rows.\n */\nexport function useChatHistorySessionsFromChannels(orgName: string | null | undefined, options?: { skip?: boolean }) {\n const skip = options?.skip || !orgName;\n const variables = useMemo(() => getHistoryChannelsQueryVariables(orgName), [orgName]);\n\n const { data, loading, error, refetch } = useGetChannelsByUserWithLastMessageQuery({\n variables,\n skip,\n fetchPolicy: 'cache-and-network',\n notifyOnNetworkStatusChange: true,\n context: { cacheKey: 'chat-history-channels-list' },\n });\n\n const sessions = useMemo(() => chatHistorySessionsFromChannels(data), [data]);\n const sourceChannelCount = data?.channelsByUser?.length ?? 0;\n /**\n * `sessionsLoaded` means \"we have data we can show\", regardless of whether a\n * background revalidation is still in flight. Same contract as `messagesLoaded`\n * in `useChatMessages` — lets the screen show the cached list (or empty state)\n * immediately on revisit instead of flashing a loader for the network round-trip.\n */\n const sessionsLoaded = data !== undefined;\n\n return { sessions, loading, sessionsLoaded, error, refetch, sourceChannelCount };\n}\n\nfunction stripModelCostHeader(content: string): string {\n const normalized = content.replace(/\\r\\n/g, '\\n');\n return normalized.replace(\n /^\\s*(?:[^\\w\\n]+\\s*)?[a-z0-9][a-z0-9._-]*\\s*\\(\\s*\\$[\\d.]+\\s*\\/\\s*MTok\\s+in\\s*\\)\\s*\\n+/i,\n '',\n );\n}\n\nfunction sanitizeAssistantContentByRole(role: unknown, content: string): string {\n return role === 'assistant' ? stripModelCostHeader(content) : content;\n}\n\nfunction omitContent<T extends Record<string, any>>(value: T | null | undefined): Omit<T, 'content'> {\n const clone = { ...(value ?? {}) } as Record<string, any>;\n delete clone.content;\n return clone as Omit<T, 'content'>;\n}\n\nexport interface ChatSessionUI {\n id: string;\n title: string;\n createdAt: Date;\n updatedAt: Date;\n messageCount?: number;\n}\n\nexport function useChatSessions(options?: { includeArchived?: boolean; skip?: boolean }) {\n const { data, loading, error, refetch } = useGetChannelsByUserWithLastMessageQuery({\n variables: AI_ASSISTANT_CHANNELS_QUERY_VARS,\n skip: options?.skip,\n fetchPolicy: 'cache-and-network',\n });\n\n const sessions: ChatSessionUI[] = useMemo(() => {\n const channels = data?.channelsByUser ?? [];\n return channels\n .filter((c): c is NonNullable<typeof c> => Boolean(c?.id))\n .map((channel) => ({\n id: channel.id,\n title: channel.title || channel.displayName || 'New Chat',\n createdAt: new Date(channel.createdAt ?? Date.now()),\n updatedAt: new Date(channel.updatedAt ?? Date.now()),\n messageCount: undefined,\n }));\n }, [data]);\n\n return { sessions, loading, error, refetch };\n}\n\nexport interface ChatMessageUI {\n id: string;\n sessionId: string;\n role: 'user' | 'assistant' | 'system';\n content: string;\n attachments?: Array<{ id: string; name: string; type: string; mimeType?: string; size?: number; url?: string }>;\n tokenCount?: number;\n model?: string;\n createdAt: Date;\n updatedAt: Date;\n}\n\ninterface MinimalFile {\n id?: string | null;\n name?: string | null;\n mimeType?: string | null;\n size?: number | null;\n url?: string | null;\n}\n\ninterface MinimalPost {\n id?: string | null;\n message?: string | null;\n createdAt?: string | null;\n updatedAt?: string | null;\n channel?: { id?: string | null } | null;\n files?: { data?: MinimalFile[] | null } | null;\n props?: { role?: string | null; tokenCount?: number | null; model?: string | null } | null;\n propsConfiguration?: {\n contents?: { role?: string | null } | null;\n content?: { role?: string | null } | null;\n } | null;\n}\n\nfunction mapPostToChatMessageUI(post: MinimalPost, fallbackChannelId: string): ChatMessageUI {\n const props = (post.props ?? {}) as Record<string, any>;\n const contents = post.propsConfiguration?.contents ?? {};\n const roleRaw = props.role ?? contents.role ?? post.propsConfiguration?.content?.role;\n let role: ChatMessageUI['role'] = 'assistant';\n if (roleRaw === 'user' || roleRaw === AiAgentMessageRole.User) role = 'user';\n else if (roleRaw === 'assistant' || roleRaw === AiAgentMessageRole.Assistant) role = 'assistant';\n else if (roleRaw === 'system') role = 'system';\n\n const rawContent = post?.message ?? '';\n const content = sanitizeAssistantContentByRole(role, rawContent);\n\n return {\n id: post?.id ?? uuidv4(),\n sessionId: post?.channel?.id ?? fallbackChannelId,\n role,\n content,\n attachments: (post?.files?.data ?? []).map((file) => ({\n id: file.id ?? uuidv4(),\n name: file.name ?? 'file',\n type: typeof file.mimeType === 'string' && file.mimeType.startsWith('image/') ? 'screenshot' : 'file',\n mimeType: file.mimeType ?? undefined,\n size: file.size ?? undefined,\n url: file.url ?? undefined,\n })),\n tokenCount: props.tokenCount ?? undefined,\n model: props.model ?? undefined,\n createdAt: post?.createdAt ? new Date(post.createdAt) : new Date(),\n updatedAt: post?.updatedAt ? new Date(post.updatedAt) : new Date(),\n };\n}\n\nexport function useChatMessages(sessionId: string | null, options?: { skip?: boolean }) {\n const { data, loading, error, refetch } = useMessagesQuery({\n variables: {\n channelId: sessionId ?? undefined,\n parentId: null,\n limit: MESSAGES_PAGE_LIMIT,\n skip: 0,\n },\n skip: !sessionId || options?.skip,\n fetchPolicy: 'cache-and-network',\n notifyOnNetworkStatusChange: true,\n /**\n * Cache key is per-channel so switching sessions doesn't read another channel's response.\n * Keeping this as a constant ('messages-list') used to cause cross-session bleed in the\n * custom Apollo link before reaching the normalized cache.\n */\n context: { cacheKey: sessionId ? `messages-list:${sessionId}` : 'messages-list' },\n });\n\n /**\n * `messagesLoaded` means \"we have data we can show\", regardless of whether a\n * background revalidation is in flight. With `cache-and-network`, Apollo\n * fills `data` from cache synchronously while `loading` is still true for\n * the network round-trip — gating hydration on `!loading` made every chat\n * revisit show a loader for the network latency even though the messages\n * were already cached. The chat stream re-hydrates whenever `data` changes,\n * so the fresh network response still swaps in silently afterward.\n */\n const messagesLoaded = data !== undefined;\n\n const messages: ChatMessageUI[] = useMemo(() => {\n if (!sessionId) return [];\n const rows = data?.messages?.data ?? [];\n return rows\n .map((post) => mapPostToChatMessageUI(post as MinimalPost, sessionId))\n .sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());\n }, [data, sessionId]);\n\n return { messages, loading, messagesLoaded, error, refetch };\n}\n\nexport type IAccountSaveChatMessagesInput = IAccountSaveChatMessagesInputBase & {\n mode?: 'plan' | 'build';\n createdBy?: string;\n};\n\n/** Backend/gateway may have already inserted the post (E11000 duplicate `_id`). */\nfunction isDuplicatePostError(error: unknown): boolean {\n const parts: string[] = [];\n if (error && typeof error === 'object' && 'graphQLErrors' in error) {\n const gqlErrors = (error as { graphQLErrors?: Array<{ message?: string }> }).graphQLErrors ?? [];\n parts.push(...gqlErrors.map((e) => e?.message ?? ''));\n }\n if (error instanceof Error) {\n parts.push(error.message);\n } else if (error != null) {\n parts.push(String(error));\n }\n const msg = parts.join(' ');\n return /E11000|duplicate key/i.test(msg);\n}\n\nexport function useChatMutations() {\n const [addChannelMutation, { loading: createChannelLoading }] = useAddChannelMutation();\n const [sendMessagesMutation, { loading: sendMessagesLoading }] = useSendMessagesMutation();\n\n const createChannel = useCallback(\n async (input?: IAccountCreateChatSessionInput): Promise<ChatSessionUI> => {\n const {\n orgName: orgNameArg,\n projectId: projectIdArg,\n ...inputForSettings\n } = (input ?? {}) as IAccountCreateChatSessionInput & {\n orgName?: string | null;\n projectId?: string | null;\n };\n const orgName =\n typeof orgNameArg === 'string' && orgNameArg.trim().length > 0 ? orgNameArg.trim() : undefined;\n const projectId =\n typeof projectIdArg === 'string' && projectIdArg.trim().length > 0 ? projectIdArg.trim() : undefined;\n\n const settings = {\n title: input?.title ?? 'New Chat',\n description: input?.systemPrompt ?? null,\n isShared: false,\n sharedSlug: null,\n isArchived: false,\n isPinned: false,\n model: input?.model ?? null,\n systemPrompt: input?.systemPrompt ?? null,\n ...inputForSettings,\n };\n\n const { data } = await addChannelMutation({\n variables: {\n channelId: input?.id ?? null,\n name: input?.title ?? 'New Chat',\n description: input?.systemPrompt ?? null,\n type: RoomType.Aiassistant,\n settings,\n ...(orgName ? { orgName } : {}),\n ...(projectId ? { projectId } : {}),\n },\n /**\n * Refetch every cache slot the rest of the app is watching for\n * channel lists. Apollo keys cached results by `variables`, so each\n * shape we emit here must match a watched query exactly.\n *\n * Variants:\n * 1. Legacy limit:100 list (web parity, no `criteria.orgName`).\n * 2. Mobile history-screen variant WITH `criteria.orgName` so the\n * resolver's `$in: [slug, orgId]` matches mobile-created channels.\n * 3. Same variant WITHOUT orgName, in case the screen mounted before\n * org settings resolved.\n */\n refetchQueries: [\n { query: GetChannelsByUserWithLastMessageDocument, variables: AI_ASSISTANT_CHANNELS_QUERY_VARS },\n ...(orgName\n ? [\n {\n query: GetChannelsByUserWithLastMessageDocument,\n variables: getHistoryChannelsQueryVariables(orgName),\n },\n ]\n : []),\n { query: GetChannelsByUserWithLastMessageDocument, variables: HISTORY_QUERY_BASE },\n ],\n awaitRefetchQueries: true,\n });\n\n if (!data?.createChannel?.id) {\n throw new Error('Failed to create channel');\n }\n\n const channel = data.createChannel;\n const title = channel.title ?? input?.title ?? 'New Chat';\n const now = new Date();\n\n return {\n id: channel.id,\n title,\n createdAt: now,\n updatedAt: now,\n };\n },\n [addChannelMutation],\n );\n\n const saveMessages = useCallback(\n async (\n input: IAccountSaveChatMessagesInput,\n ): Promise<{\n userMessage: ChatMessageUI;\n assistantMessage: ChatMessageUI;\n session: ChatSessionUI;\n }> => {\n const sanitizedAssistantContent = stripModelCostHeader(input.assistantMessage.content ?? '');\n const assistantMessageWithoutContent = omitContent((input.assistantMessage as any) ?? {});\n\n let userPost: MinimalPost | null | undefined;\n try {\n const userResult = await sendMessagesMutation({\n variables: {\n channelId: input.sessionId,\n type: RoomType.Aiassistant,\n content: input.userMessage.content ?? '',\n ...(input.createdBy ? { createdBy: input.createdBy } : {}),\n extraProps: {\n type: PostTypeEnum.Aiassistant,\n role: 'user',\n attachments: input.userMessage.attachments ?? [],\n isActive: true,\n status: 'complete',\n ...(input.userMessage as any),\n ...(input.mode ? { mode: input.mode } : {}),\n },\n } as any,\n });\n userPost = userResult.data?.sendMessage as MinimalPost | undefined;\n } catch (err) {\n if (!isDuplicatePostError(err)) {\n throw err;\n }\n console.warn('[saveMessages] user post already persisted (skipping duplicate insert)');\n }\n\n /**\n * Keep the prompting user post id in metadata. `sendMessage.postId` is the id of\n * the post being created, so reusing the user post id for the assistant reply would\n * collide and leave only the user message persisted.\n */\n const userPostId = userPost?.id ?? null;\n\n let assistantPost: MinimalPost | null | undefined;\n try {\n const assistantResult = await sendMessagesMutation({\n variables: {\n channelId: input.sessionId,\n type: RoomType.Aiassistant,\n content: sanitizedAssistantContent,\n extraProps: {\n type: PostTypeEnum.Aiassistant,\n role: 'assistant',\n attachments: input.assistantMessage.attachments ?? [],\n tokenCount: input.assistantMessage.tokenCount,\n latencyMs: input.assistantMessage.latencyMs,\n model: input.assistantMessage.model,\n finishReason: (input.assistantMessage as any).finishReason ?? null,\n isActive: true,\n status: 'complete',\n ...assistantMessageWithoutContent,\n ...(userPostId ? { parentId: userPostId } : {}),\n ...(input.mode ? { mode: input.mode } : {}),\n },\n } as any,\n });\n assistantPost = assistantResult.data?.sendMessage as MinimalPost | undefined;\n } catch (err) {\n if (!isDuplicatePostError(err)) {\n throw err;\n }\n console.warn('[saveMessages] assistant post already persisted (skipping duplicate insert)');\n }\n\n if (!userPost && !assistantPost) {\n throw new Error('Failed to send messages');\n }\n\n const now = new Date();\n const fallbackUser: ChatMessageUI = {\n id: userPostId ?? uuidv4(),\n sessionId: input.sessionId,\n role: 'user',\n content: input.userMessage.content ?? '',\n createdAt: now,\n updatedAt: now,\n };\n const fallbackAssistant: ChatMessageUI = {\n id: uuidv4(),\n sessionId: input.sessionId,\n role: 'assistant',\n content: sanitizedAssistantContent,\n createdAt: now,\n updatedAt: now,\n tokenCount: input.assistantMessage.tokenCount,\n model: input.assistantMessage.model,\n };\n return {\n userMessage: userPost ? mapPostToChatMessageUI(userPost, input.sessionId) : fallbackUser,\n assistantMessage: assistantPost\n ? mapPostToChatMessageUI(assistantPost, input.sessionId)\n : fallbackAssistant,\n session: {\n id: input.sessionId,\n title: 'Chat',\n createdAt: now,\n updatedAt: now,\n },\n };\n },\n [sendMessagesMutation],\n );\n\n return {\n createChannel,\n createSession: createChannel,\n saveMessages,\n loading: { create: createChannelLoading, saveMessages: sendMessagesLoading },\n };\n}\n"],"names":["uuidv4","_a","_b","_c","_d","_e"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {DEFAULT_PRODUCTION_TAG_ID}from'@adminide-stack/core/lib/constants/defaultIds.js';import {isAuthenticatedSelector}from'@adminide-stack/user-auth0-client';import {
|
|
1
|
+
import {DEFAULT_PRODUCTION_TAG_ID}from'@adminide-stack/core/lib/constants/defaultIds.js';import {useContextData}from'@adminide-stack/platform-client/lib/hooks/useContextData.js';import {isAuthenticatedSelector}from'@adminide-stack/user-auth0-client';import {useAccountProfileQuery,useGetUserOrganizationsWithDetailsQuery,useGetUserOrganizationsQuery,useGetProjectsLazyQuery,useQuickCreateProjectForAccountBkMutation,useCreateVaultMutation}from'common/graphql';import {useMemo,useEffect,useState,useRef}from'react';import {useSelector}from'react-redux';import {useAccountDefaultSettings}from'./useAccountDefaultSettings.js';import {isUnhydratedCdecodeUri,toUriInput,settingsUriForAccount}from'../utils/cdecodeUri.js';const uuidToObjectId = (uuid) => uuid.replace(/-/g, "").substring(0, 24);
|
|
2
2
|
const PROJECT_NAME = "DEFAULT_YANTRA_PROJECT";
|
|
3
3
|
const TAG_ID = uuidToObjectId(DEFAULT_PRODUCTION_TAG_ID);
|
|
4
4
|
const ORG_RESOLVE_POLL_MS = 2e3;
|
|
@@ -10,15 +10,15 @@ function pickDefaultOrgSlug(orgs) {
|
|
|
10
10
|
return (_b = (_a = first == null ? void 0 : first.name) == null ? void 0 : _a.trim()) != null ? _b : null;
|
|
11
11
|
}
|
|
12
12
|
function usePrerequisiteIds() {
|
|
13
|
-
var _a, _b, _c, _d
|
|
13
|
+
var _a, _b, _c, _d;
|
|
14
14
|
const isAuthenticated = useSelector(isAuthenticatedSelector);
|
|
15
15
|
const {
|
|
16
16
|
data: contextData,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const cdecodeUri =
|
|
21
|
-
const contextUserId = (
|
|
17
|
+
complete: contextComplete
|
|
18
|
+
} = useContextData();
|
|
19
|
+
const contextLoading = !contextComplete;
|
|
20
|
+
const cdecodeUri = contextData == null ? void 0 : contextData.cdecodeUri;
|
|
21
|
+
const contextUserId = (_a = contextData == null ? void 0 : contextData.userId) != null ? _a : null;
|
|
22
22
|
const contextResourceUri = useMemo(() => {
|
|
23
23
|
if (isUnhydratedCdecodeUri(cdecodeUri)) return void 0;
|
|
24
24
|
return toUriInput(cdecodeUri);
|
|
@@ -32,7 +32,7 @@ function usePrerequisiteIds() {
|
|
|
32
32
|
errorPolicy: "all",
|
|
33
33
|
skip: !isAuthenticated
|
|
34
34
|
});
|
|
35
|
-
const profileUserId = (
|
|
35
|
+
const profileUserId = (_d = (_c = (_b = accountProfileData == null ? void 0 : accountProfileData.accountProfile) == null ? void 0 : _b.user) == null ? void 0 : _c.id) != null ? _d : null;
|
|
36
36
|
const effectiveUserId = isAuthenticated ? profileUserId || contextUserId : null;
|
|
37
37
|
useEffect(() => {
|
|
38
38
|
if (!isAuthenticated || profileUserId) return;
|
|
@@ -98,10 +98,6 @@ function usePrerequisiteIds() {
|
|
|
98
98
|
}, [cdecodeUri]);
|
|
99
99
|
const orgName = orgFromContextSettings || orgFromAccountSettings || orgFromMembership || orgFromContextPath || null;
|
|
100
100
|
const rawSettingsProjectId = projectFromContextSettings || projectFromAccountSettings || null;
|
|
101
|
-
useEffect(() => {
|
|
102
|
-
if (!orgName) return;
|
|
103
|
-
refetchContext().catch(() => void 0);
|
|
104
|
-
}, [orgName, refetchContext]);
|
|
105
101
|
useEffect(() => {
|
|
106
102
|
if (!isAuthenticated || orgName || !effectiveUserId) return;
|
|
107
103
|
const timer = setInterval(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePrerequisiteIds.js","sources":["../../src/hooks/usePrerequisiteIds.ts"],"sourcesContent":["import { DEFAULT_PRODUCTION_TAG_ID } from '@adminide-stack/core/lib/constants/defaultIds.js';\nimport { isAuthenticatedSelector } from '@adminide-stack/user-auth0-client';\nimport {\n useAccountProfileQuery,\n useCreateVaultMutation,\n useGetContextDataQuery,\n useGetProjectsLazyQuery,\n useGetUserOrganizationsQuery,\n useGetUserOrganizationsWithDetailsQuery,\n useQuickCreateProjectForAccountBkMutation,\n} from 'common/graphql';\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport { useSelector } from 'react-redux';\nimport { useAccountDefaultSettings } from './useAccountDefaultSettings';\nimport { isUnhydratedCdecodeUri, settingsUriForAccount, toUriInput } from '../utils/cdecodeUri';\n\nconst uuidToObjectId = (uuid: string) => uuid.replace(/-/g, '').substring(0, 24);\n\nconst PROJECT_NAME = 'DEFAULT_YANTRA_PROJECT';\nconst TAG_ID = uuidToObjectId(DEFAULT_PRODUCTION_TAG_ID);\n\nconst ORG_RESOLVE_POLL_MS = 2000;\nconst PROFILE_POLL_MS = 1500;\n\nfunction pickDefaultOrgSlug(\n orgs: Array<{ name?: string | null; title?: string | null } | null | undefined> | null | undefined,\n): string | null {\n if (!orgs?.length) return null;\n const first = orgs.find((o) => typeof o?.name === 'string' && o.name.trim().length > 0);\n return first?.name?.trim() ?? null;\n}\n\n/**\n * Org + project prerequisites for mobile (parity with browser `usePrerequisiteIds`).\n *\n * Settings use the same `account.default` config as web (`useSettingsLoader` → `useSettings` on mobile).\n * After verify-user, account-level settings (`//accounts/{id}#settings`) and org membership are polled\n * until `organization` is available, then route context is synced on Home.\n */\nexport function usePrerequisiteIds() {\n const isAuthenticated = useSelector(isAuthenticatedSelector);\n\n const { data: contextData, loading: contextLoading, refetch: refetchContext } = useGetContextDataQuery();\n const cdecodeUri = contextData?.getContextData?.cdecodeUri;\n const contextUserId = contextData?.getContextData?.userId ?? null;\n\n const contextResourceUri = useMemo(() => {\n if (isUnhydratedCdecodeUri(cdecodeUri)) return undefined;\n return toUriInput(cdecodeUri);\n }, [cdecodeUri]);\n\n const {\n data: accountProfileData,\n loading: userLoading,\n refetch: refetchProfile,\n } = useAccountProfileQuery({\n fetchPolicy: 'cache-and-network',\n errorPolicy: 'all',\n skip: !isAuthenticated,\n });\n const profileUserId = accountProfileData?.accountProfile?.user?.id ?? null;\n const effectiveUserId = isAuthenticated ? profileUserId || contextUserId : null;\n\n useEffect(() => {\n if (!isAuthenticated || profileUserId) return;\n const timer = setInterval(() => {\n refetchProfile().catch(() => undefined);\n }, PROFILE_POLL_MS);\n return () => clearInterval(timer);\n }, [isAuthenticated, profileUserId, refetchProfile]);\n\n // Step 1 (web): account.default via settings loader — context cdecodeUri when hydrated\n const {\n organization: orgFromContextSettings,\n project: projectFromContextSettings,\n loading: contextSettingsLoading,\n refetch: refetchContextSettings,\n } = useAccountDefaultSettings({\n resourceUri: contextResourceUri,\n skip: !isAuthenticated || !contextResourceUri,\n });\n\n const accountResourceUri = useMemo(() => {\n if (!effectiveUserId || orgFromContextSettings) return undefined;\n return settingsUriForAccount(effectiveUserId);\n }, [effectiveUserId, orgFromContextSettings]);\n\n // Mobile bootstrap: read account.default from account document before org is on the route\n const {\n organization: orgFromAccountSettings,\n project: projectFromAccountSettings,\n loading: accountSettingsLoading,\n refetch: refetchAccountSettings,\n } = useAccountDefaultSettings({\n resourceUri: accountResourceUri,\n skip: !isAuthenticated || !accountResourceUri,\n });\n\n const {\n data: orgsData,\n loading: orgsLoading,\n refetch: refetchOrgs,\n } = useGetUserOrganizationsWithDetailsQuery({\n skip: !isAuthenticated || !effectiveUserId,\n fetchPolicy: 'cache-and-network',\n });\n\n const {\n data: orgsByUserData,\n loading: orgsByUserLoading,\n refetch: refetchOrgsByUser,\n } = useGetUserOrganizationsQuery({\n variables: { userId: effectiveUserId ?? undefined },\n skip: !isAuthenticated || !effectiveUserId,\n fetchPolicy: 'cache-and-network',\n });\n\n const orgFromMembership = useMemo(() => {\n const fromDetails = pickDefaultOrgSlug(orgsData?.getUserOrganizationsWithDetails);\n if (fromDetails) return fromDetails;\n return pickDefaultOrgSlug(orgsByUserData?.getUserOrganizations);\n }, [orgsData, orgsByUserData]);\n\n const orgFromContextPath = useMemo(() => {\n if (isUnhydratedCdecodeUri(cdecodeUri)) return null;\n const { path } = toUriInput(cdecodeUri);\n const match = path.match(/^\\/([^/]+)\\//);\n return match?.[1]?.trim() || null;\n }, [cdecodeUri]);\n\n const orgName = orgFromContextSettings || orgFromAccountSettings || orgFromMembership || orgFromContextPath || null;\n\n const rawSettingsProjectId = projectFromContextSettings || projectFromAccountSettings || null;\n\n useEffect(() => {\n if (!orgName) return;\n refetchContext().catch(() => undefined);\n }, [orgName, refetchContext]);\n\n useEffect(() => {\n if (!isAuthenticated || orgName || !effectiveUserId) return;\n const timer = setInterval(() => {\n refetchContextSettings?.()?.catch(() => undefined);\n refetchAccountSettings?.()?.catch(() => undefined);\n refetchOrgs().catch(() => undefined);\n refetchOrgsByUser().catch(() => undefined);\n }, ORG_RESOLVE_POLL_MS);\n return () => clearInterval(timer);\n }, [\n isAuthenticated,\n orgName,\n effectiveUserId,\n refetchContextSettings,\n refetchAccountSettings,\n refetchOrgs,\n refetchOrgsByUser,\n ]);\n\n const settingsProjectId = rawSettingsProjectId;\n\n const [resolvedProjectId, setResolvedProjectId] = useState<string | null>(null);\n const [isInitializingProject, setIsInitializingProject] = useState(false);\n const isCreatingRef = useRef(false);\n\n const projectId = settingsProjectId || resolvedProjectId;\n const needsProjectCreation = !!orgName && !rawSettingsProjectId && !projectId;\n\n const [fetchProjects] = useGetProjectsLazyQuery();\n const [createProject, { error: createError, loading: projectCreating }] =\n useQuickCreateProjectForAccountBkMutation();\n const [createVault, { error: vaultCreateError }] = useCreateVaultMutation();\n\n useEffect(() => {\n if (!needsProjectCreation || isCreatingRef.current || !effectiveUserId || userLoading) {\n return;\n }\n\n isCreatingRef.current = true;\n setIsInitializingProject(true);\n\n createProject({\n variables: {\n input: {\n accountId: effectiveUserId,\n projectName: PROJECT_NAME,\n },\n },\n onCompleted: (data) => {\n const newMongoProjectId = data.quickCreateProjectForAccount?.id;\n if (!newMongoProjectId) {\n isCreatingRef.current = false;\n setIsInitializingProject(false);\n console.error('[usePrerequisiteIds] Project creation returned no id');\n return;\n }\n\n fetchProjects({\n variables: { orgName: orgName!, limit: 50 },\n })\n .then(({ data: projectsData }) => {\n const createdProject = (projectsData?.getProjects?.data || []).find(\n (project) => project?.id === newMongoProjectId,\n );\n if (createdProject?.projectId) {\n setResolvedProjectId(createdProject.projectId);\n }\n })\n .catch((error) => {\n console.error('[usePrerequisiteIds] Failed to resolve created project UUID:', error.message);\n })\n .finally(() => {\n setIsInitializingProject(false);\n });\n\n createVault({\n variables: {\n input: {\n orgName: orgName!,\n projectId: newMongoProjectId,\n },\n },\n onCompleted: () => {\n console.log('[usePrerequisiteIds] Vault created for project:', newMongoProjectId);\n },\n onError: (error) => {\n console.error('[usePrerequisiteIds] Vault creation failed:', error.message);\n },\n });\n },\n onError: (error) => {\n console.error('[usePrerequisiteIds] Project creation failed:', error.message);\n isCreatingRef.current = false;\n setIsInitializingProject(false);\n },\n });\n }, [createProject, createVault, fetchProjects, needsProjectCreation, orgName, effectiveUserId, userLoading]);\n\n const settingsLoading = contextSettingsLoading || accountSettingsLoading;\n\n const isOrgLoading =\n isAuthenticated &&\n !orgName &&\n (userLoading ||\n contextLoading ||\n settingsLoading ||\n orgsLoading ||\n orgsByUserLoading ||\n Boolean(effectiveUserId));\n\n const isProjectLoading =\n !!orgName && !rawSettingsProjectId && !projectId && (isInitializingProject || projectCreating);\n\n const isLoading = isOrgLoading || isProjectLoading;\n\n return {\n projectId,\n orgName,\n accountUserId: effectiveUserId ?? null,\n tagId: TAG_ID,\n loading: isLoading,\n /** True while org slug is still unknown (Home should wait before syncing route). */\n orgLoading: isOrgLoading,\n errors: { createError, vaultCreateError },\n };\n}\n"],"names":["_a","_b"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"usePrerequisiteIds.js","sources":["../../src/hooks/usePrerequisiteIds.ts"],"sourcesContent":["import { DEFAULT_PRODUCTION_TAG_ID } from '@adminide-stack/core/lib/constants/defaultIds.js';\nimport { useContextData } from '@adminide-stack/platform-client/lib/hooks/useContextData.js';\nimport { isAuthenticatedSelector } from '@adminide-stack/user-auth0-client';\nimport {\n useAccountProfileQuery,\n useCreateVaultMutation,\n useGetProjectsLazyQuery,\n useGetUserOrganizationsQuery,\n useGetUserOrganizationsWithDetailsQuery,\n useQuickCreateProjectForAccountBkMutation,\n} from 'common/graphql';\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport { useSelector } from 'react-redux';\nimport { useAccountDefaultSettings } from './useAccountDefaultSettings';\nimport { isUnhydratedCdecodeUri, settingsUriForAccount, toUriInput } from '../utils/cdecodeUri';\n\nconst uuidToObjectId = (uuid: string) => uuid.replace(/-/g, '').substring(0, 24);\n\nconst PROJECT_NAME = 'DEFAULT_YANTRA_PROJECT';\nconst TAG_ID = uuidToObjectId(DEFAULT_PRODUCTION_TAG_ID);\n\nconst ORG_RESOLVE_POLL_MS = 2000;\nconst PROFILE_POLL_MS = 1500;\n\nfunction pickDefaultOrgSlug(\n orgs: Array<{ name?: string | null; title?: string | null } | null | undefined> | null | undefined,\n): string | null {\n if (!orgs?.length) return null;\n const first = orgs.find((o) => typeof o?.name === 'string' && o.name.trim().length > 0);\n return first?.name?.trim() ?? null;\n}\n\n/**\n * Org + project prerequisites for mobile (parity with browser `usePrerequisiteIds`).\n *\n * Settings use the same `account.default` config as web (`useSettingsLoader` → `useSettings` on mobile).\n * After verify-user, account-level settings (`//accounts/{id}#settings`) and org membership are polled\n * until `organization` is available, then route context is synced on Home.\n */\nexport function usePrerequisiteIds() {\n const isAuthenticated = useSelector(isAuthenticatedSelector);\n\n const { data: contextData, complete: contextComplete } = useContextData();\n const contextLoading = !contextComplete;\n const cdecodeUri = contextData?.cdecodeUri;\n const contextUserId = contextData?.userId ?? null;\n\n const contextResourceUri = useMemo(() => {\n if (isUnhydratedCdecodeUri(cdecodeUri)) return undefined;\n return toUriInput(cdecodeUri);\n }, [cdecodeUri]);\n\n const {\n data: accountProfileData,\n loading: userLoading,\n refetch: refetchProfile,\n } = useAccountProfileQuery({\n fetchPolicy: 'cache-and-network',\n errorPolicy: 'all',\n skip: !isAuthenticated,\n });\n const profileUserId = accountProfileData?.accountProfile?.user?.id ?? null;\n const effectiveUserId = isAuthenticated ? profileUserId || contextUserId : null;\n\n useEffect(() => {\n if (!isAuthenticated || profileUserId) return;\n const timer = setInterval(() => {\n refetchProfile().catch(() => undefined);\n }, PROFILE_POLL_MS);\n return () => clearInterval(timer);\n }, [isAuthenticated, profileUserId, refetchProfile]);\n\n // Step 1 (web): account.default via settings loader — context cdecodeUri when hydrated\n const {\n organization: orgFromContextSettings,\n project: projectFromContextSettings,\n loading: contextSettingsLoading,\n refetch: refetchContextSettings,\n } = useAccountDefaultSettings({\n resourceUri: contextResourceUri,\n skip: !isAuthenticated || !contextResourceUri,\n });\n\n const accountResourceUri = useMemo(() => {\n if (!effectiveUserId || orgFromContextSettings) return undefined;\n return settingsUriForAccount(effectiveUserId);\n }, [effectiveUserId, orgFromContextSettings]);\n\n // Mobile bootstrap: read account.default from account document before org is on the route\n const {\n organization: orgFromAccountSettings,\n project: projectFromAccountSettings,\n loading: accountSettingsLoading,\n refetch: refetchAccountSettings,\n } = useAccountDefaultSettings({\n resourceUri: accountResourceUri,\n skip: !isAuthenticated || !accountResourceUri,\n });\n\n const {\n data: orgsData,\n loading: orgsLoading,\n refetch: refetchOrgs,\n } = useGetUserOrganizationsWithDetailsQuery({\n skip: !isAuthenticated || !effectiveUserId,\n fetchPolicy: 'cache-and-network',\n });\n\n const {\n data: orgsByUserData,\n loading: orgsByUserLoading,\n refetch: refetchOrgsByUser,\n } = useGetUserOrganizationsQuery({\n variables: { userId: effectiveUserId ?? undefined },\n skip: !isAuthenticated || !effectiveUserId,\n fetchPolicy: 'cache-and-network',\n });\n\n const orgFromMembership = useMemo(() => {\n const fromDetails = pickDefaultOrgSlug(orgsData?.getUserOrganizationsWithDetails);\n if (fromDetails) return fromDetails;\n return pickDefaultOrgSlug(orgsByUserData?.getUserOrganizations);\n }, [orgsData, orgsByUserData]);\n\n const orgFromContextPath = useMemo(() => {\n if (isUnhydratedCdecodeUri(cdecodeUri)) return null;\n const { path } = toUriInput(cdecodeUri);\n const match = path.match(/^\\/([^/]+)\\//);\n return match?.[1]?.trim() || null;\n }, [cdecodeUri]);\n\n const orgName = orgFromContextSettings || orgFromAccountSettings || orgFromMembership || orgFromContextPath || null;\n\n const rawSettingsProjectId = projectFromContextSettings || projectFromAccountSettings || null;\n\n useEffect(() => {\n if (!isAuthenticated || orgName || !effectiveUserId) return;\n const timer = setInterval(() => {\n refetchContextSettings?.()?.catch(() => undefined);\n refetchAccountSettings?.()?.catch(() => undefined);\n refetchOrgs().catch(() => undefined);\n refetchOrgsByUser().catch(() => undefined);\n }, ORG_RESOLVE_POLL_MS);\n return () => clearInterval(timer);\n }, [\n isAuthenticated,\n orgName,\n effectiveUserId,\n refetchContextSettings,\n refetchAccountSettings,\n refetchOrgs,\n refetchOrgsByUser,\n ]);\n\n const settingsProjectId = rawSettingsProjectId;\n\n const [resolvedProjectId, setResolvedProjectId] = useState<string | null>(null);\n const [isInitializingProject, setIsInitializingProject] = useState(false);\n const isCreatingRef = useRef(false);\n\n const projectId = settingsProjectId || resolvedProjectId;\n const needsProjectCreation = !!orgName && !rawSettingsProjectId && !projectId;\n\n const [fetchProjects] = useGetProjectsLazyQuery();\n const [createProject, { error: createError, loading: projectCreating }] =\n useQuickCreateProjectForAccountBkMutation();\n const [createVault, { error: vaultCreateError }] = useCreateVaultMutation();\n\n useEffect(() => {\n if (!needsProjectCreation || isCreatingRef.current || !effectiveUserId || userLoading) {\n return;\n }\n\n isCreatingRef.current = true;\n setIsInitializingProject(true);\n\n createProject({\n variables: {\n input: {\n accountId: effectiveUserId,\n projectName: PROJECT_NAME,\n },\n },\n onCompleted: (data) => {\n const newMongoProjectId = data.quickCreateProjectForAccount?.id;\n if (!newMongoProjectId) {\n isCreatingRef.current = false;\n setIsInitializingProject(false);\n console.error('[usePrerequisiteIds] Project creation returned no id');\n return;\n }\n\n fetchProjects({\n variables: { orgName: orgName!, limit: 50 },\n })\n .then(({ data: projectsData }) => {\n const createdProject = (projectsData?.getProjects?.data || []).find(\n (project) => project?.id === newMongoProjectId,\n );\n if (createdProject?.projectId) {\n setResolvedProjectId(createdProject.projectId);\n }\n })\n .catch((error) => {\n console.error('[usePrerequisiteIds] Failed to resolve created project UUID:', error.message);\n })\n .finally(() => {\n setIsInitializingProject(false);\n });\n\n createVault({\n variables: {\n input: {\n orgName: orgName!,\n projectId: newMongoProjectId,\n },\n },\n onCompleted: () => {\n console.log('[usePrerequisiteIds] Vault created for project:', newMongoProjectId);\n },\n onError: (error) => {\n console.error('[usePrerequisiteIds] Vault creation failed:', error.message);\n },\n });\n },\n onError: (error) => {\n console.error('[usePrerequisiteIds] Project creation failed:', error.message);\n isCreatingRef.current = false;\n setIsInitializingProject(false);\n },\n });\n }, [createProject, createVault, fetchProjects, needsProjectCreation, orgName, effectiveUserId, userLoading]);\n\n const settingsLoading = contextSettingsLoading || accountSettingsLoading;\n\n const isOrgLoading =\n isAuthenticated &&\n !orgName &&\n (userLoading ||\n contextLoading ||\n settingsLoading ||\n orgsLoading ||\n orgsByUserLoading ||\n Boolean(effectiveUserId));\n\n const isProjectLoading =\n !!orgName && !rawSettingsProjectId && !projectId && (isInitializingProject || projectCreating);\n\n const isLoading = isOrgLoading || isProjectLoading;\n\n return {\n projectId,\n orgName,\n accountUserId: effectiveUserId ?? null,\n tagId: TAG_ID,\n loading: isLoading,\n /** True while org slug is still unknown (Home should wait before syncing route). */\n orgLoading: isOrgLoading,\n errors: { createError, vaultCreateError },\n };\n}\n"],"names":["_a","_b"],"mappings":"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"}
|
|
@@ -23,7 +23,8 @@ function newRequestId() {
|
|
|
23
23
|
if (c == null ? void 0 : c.randomUUID) return c.randomUUID();
|
|
24
24
|
return v4();
|
|
25
25
|
}
|
|
26
|
-
const
|
|
26
|
+
const OPENCLAW_MIN_PROTOCOL_VERSION = 3;
|
|
27
|
+
const OPENCLAW_PROTOCOL_VERSION = 4;
|
|
27
28
|
const CONNECT_TIMEOUT_MS = 3e4;
|
|
28
29
|
const RPC_TIMEOUT_MS = 3e4;
|
|
29
30
|
function deepMerge(target, source) {
|
|
@@ -112,8 +113,8 @@ class GatewayClient {
|
|
|
112
113
|
if (frame.type === "event" && frame.event === "connect.challenge") {
|
|
113
114
|
sawChallenge = true;
|
|
114
115
|
this.request("connect", {
|
|
115
|
-
minProtocol:
|
|
116
|
-
maxProtocol:
|
|
116
|
+
minProtocol: OPENCLAW_MIN_PROTOCOL_VERSION,
|
|
117
|
+
maxProtocol: OPENCLAW_PROTOCOL_VERSION,
|
|
117
118
|
client: {
|
|
118
119
|
id: "openclaw-control-ui",
|
|
119
120
|
version: "1.0.0",
|
|
@@ -152,7 +153,7 @@ class GatewayClient {
|
|
|
152
153
|
this._connected = true;
|
|
153
154
|
const syntheticHello = {
|
|
154
155
|
type: "hello-ok",
|
|
155
|
-
protocol:
|
|
156
|
+
protocol: OPENCLAW_PROTOCOL_VERSION,
|
|
156
157
|
server: {
|
|
157
158
|
version: "unknown",
|
|
158
159
|
connId: "pooled"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gatewayClient.js","sources":["../../src/services/gatewayClient.ts"],"sourcesContent":["/**\n * OpenClaw Gateway WebSocket client for yantra-app.\n *\n * Speaks the gateway's protocol v3:\n * 1. Client opens WebSocket to /ws/openclaw-chat (backend proxy)\n * 2. Gateway sends connect.challenge event with nonce\n * 3. Client sends connect request with auth token\n * 4. Gateway replies with hello-ok (available methods, events, snapshot)\n * 5. Client sends RPC requests, gateway replies; chat streams via events\n */\n\nimport { v4 as uuidv4 } from 'uuid';\n\nfunction newRequestId(): string {\n const c = globalThis.crypto as Crypto | undefined;\n if (c?.randomUUID) return c.randomUUID();\n return uuidv4();\n}\n\n// ─── Protocol Constants ─────────────────────────────────────────\n\nconst PROTOCOL_VERSION = 3;\nconst CONNECT_TIMEOUT_MS = 30_000;\nconst RPC_TIMEOUT_MS = 30_000;\n\n// ─── Protocol Frame Types ───────────────────────────────────────\n\ninterface RequestFrame {\n type: 'req';\n id: string;\n method: string;\n params?: unknown;\n}\n\ninterface ResponseFrame {\n type: 'res';\n id: string;\n ok: boolean;\n payload?: unknown;\n error?: { code: string; message: string; retryable?: boolean };\n}\n\ninterface EventFrame {\n type: 'event';\n event: string;\n payload?: unknown;\n seq?: number;\n}\n\ntype Frame = RequestFrame | ResponseFrame | EventFrame;\n\n// ─── Public Types ───────────────────────────────────────────────\n\nexport interface HelloOk {\n type: 'hello-ok';\n protocol: number;\n server: { version: string; connId: string };\n features: { methods: string[]; events: string[] };\n snapshot: Record<string, unknown>;\n policy: { maxPayload: number; maxBufferedBytes: number; tickIntervalMs: number };\n}\n\nexport interface GatewayModel {\n id: string;\n name: string;\n provider: string;\n available: boolean;\n}\n\nexport interface GatewayAgent {\n id: string;\n name?: string;\n}\n\nexport interface GatewayAgentDetail {\n agentId: string;\n workspace: string;\n files: Array<{ name: string; path: string; missing: boolean; size?: number }>;\n}\n\nexport interface ChatSendResponse {\n runId: string;\n status: 'started' | 'queued';\n}\n\nexport interface ChatStreamEvent {\n runId: string;\n sessionKey: string;\n seq: number;\n state: 'delta' | 'final' | 'aborted' | 'error';\n message?: {\n role: string;\n content: string | Array<{ type: string; text?: string; [k: string]: unknown }>;\n usage?: { inputTokens?: number; outputTokens?: number };\n stopReason?: string;\n };\n errorMessage?: string;\n}\n\nexport interface ChatHistoryResponse {\n sessionKey: string;\n sessionId?: string;\n messages: Array<{\n role: string;\n content: string | Array<{ type: string; text?: string; [k: string]: unknown }>;\n timestamp?: number;\n usage?: { inputTokens?: number; outputTokens?: number };\n }>;\n}\n\nexport interface SkillInfo {\n skillKey: string;\n name: string;\n description?: string;\n eligible: boolean;\n enabled?: boolean;\n missing?: { env?: string[]; binaries?: string[] };\n}\n\nexport interface GatewayStatus {\n healthy: boolean;\n uptime?: number;\n version?: string;\n connId?: string;\n}\n\nexport interface ChannelStatusEntry {\n channel: string;\n accountId?: string;\n configured: boolean;\n connected: boolean;\n enabled: boolean;\n error?: string;\n linked?: boolean;\n running?: boolean;\n lastError?: string;\n [key: string]: unknown;\n}\n\nexport interface ChannelsStatusResponse {\n channels: ChannelStatusEntry[];\n}\n\n// ─── Pending Request Tracker ────────────────────────────────────\n\ninterface Pending {\n resolve: (value: unknown) => void;\n reject: (err: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n}\n\n// ─── Helpers ────────────────────────────────────────────────────\n\nfunction deepMerge(target: Record<string, unknown>, source: Record<string, unknown>): Record<string, unknown> {\n const result: Record<string, unknown> = { ...target };\n for (const key of Object.keys(source)) {\n const sv = source[key];\n const tv = result[key];\n if (sv && typeof sv === 'object' && !Array.isArray(sv) && tv && typeof tv === 'object' && !Array.isArray(tv)) {\n result[key] = deepMerge(tv as Record<string, unknown>, sv as Record<string, unknown>);\n } else {\n result[key] = sv;\n }\n }\n return result;\n}\n\n// ─── GatewayClient ──────────────────────────────────────────────\n\n/**\n * WebSocket client for communicating with an OpenClaw gateway\n * through the backend chat proxy (/ws/openclaw-chat).\n */\nexport class GatewayClient {\n private ws: WebSocket | null = null;\n\n private pending = new Map<string, Pending>();\n\n private _connected = false;\n\n private _hello: HelloOk | null = null;\n\n private _eventHandlers = new Map<string, Set<(payload: unknown) => void>>();\n\n private readonly url: string;\n\n private readonly token: string;\n\n private readonly wsProtocol?: string;\n\n constructor(url: string, token: string, wsProtocol?: string) {\n this.url = url;\n this.token = token;\n this.wsProtocol = wsProtocol;\n }\n\n get connected(): boolean {\n return this._connected;\n }\n\n get hello(): HelloOk | null {\n return this._hello;\n }\n\n /** Register an event handler for gateway push events. */\n on(event: string, handler: (payload: unknown) => void): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n }\n\n /** Remove an event handler. */\n off(event: string, handler: (payload: unknown) => void): void {\n this._eventHandlers.get(event)?.delete(handler);\n }\n\n /** Connect to the gateway and authenticate. Resolves with HelloOk on success. */\n connect(): Promise<HelloOk> {\n return new Promise((resolve, reject) => {\n let settled = false;\n let timer: ReturnType<typeof setTimeout>;\n let sawChallenge = false;\n const settle = (fn: () => void) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n fn();\n };\n\n timer = setTimeout(\n () => settle(() => reject(new Error(`connect timeout after ${CONNECT_TIMEOUT_MS}ms`))),\n CONNECT_TIMEOUT_MS,\n );\n\n this.ws = this.wsProtocol ? new WebSocket(this.url, this.wsProtocol) : new WebSocket(this.url);\n\n this.ws.onerror = (ev) => {\n console.error(`[GatewayClient] WS error: url=${this.url}`, ev);\n settle(() => reject(new Error('WebSocket connection error')));\n };\n\n this.ws.onclose = (ev) => {\n this._connected = false;\n this.flushPending(new Error('connection closed'));\n const detail = ev.reason ? ` reason=\"${ev.reason}\"` : '';\n console.warn(\n `[GatewayClient] WS closed: code=${ev.code}${detail} url=${this.url} challengeReceived=${sawChallenge}`,\n );\n settle(() => reject(new Error(`connection closed before handshake (code=${ev.code})`)));\n this.emit('disconnect', { code: ev.code, reason: ev.reason });\n };\n\n this.ws.onmessage = (event) => {\n const raw = typeof event.data === 'string' ? event.data : String(event.data);\n let frame: Frame;\n try {\n frame = JSON.parse(raw);\n } catch {\n return;\n }\n\n // Handle connect.challenge → send connect request (fresh connection)\n if (frame.type === 'event' && frame.event === 'connect.challenge') {\n sawChallenge = true;\n this.request<HelloOk>('connect', {\n minProtocol: PROTOCOL_VERSION,\n maxProtocol: PROTOCOL_VERSION,\n client: {\n id: 'openclaw-control-ui',\n version: '1.0.0',\n platform: 'react-native',\n mode: 'ui',\n displayName: 'Yantra App',\n },\n role: 'operator',\n scopes: ['operator.admin', 'operator.read', 'operator.write'],\n caps: [],\n auth: { token: this.token },\n })\n .then((hello) => {\n this._connected = true;\n this._hello = hello;\n settle(() => resolve(hello));\n })\n .catch((err) => settle(() => reject(err)));\n return;\n }\n\n // Handle response frames\n if (frame.type === 'res') {\n const p = this.pending.get(frame.id);\n if (p) {\n clearTimeout(p.timer);\n this.pending.delete(frame.id);\n if (frame.ok) {\n p.resolve(frame.payload);\n } else {\n p.reject(new Error(frame.error?.message ?? 'RPC error'));\n }\n }\n return;\n }\n\n // Handle event frames\n if (frame.type === 'event') {\n // Pooled/pre-authenticated connection: receiving events without\n // a prior connect.challenge means the proxy reused an already-\n // authenticated server→gateway WS. Consider ourselves connected.\n if (!sawChallenge && !this._connected) {\n this._connected = true;\n const syntheticHello: HelloOk = {\n type: 'hello-ok',\n protocol: PROTOCOL_VERSION,\n server: { version: 'unknown', connId: 'pooled' },\n features: { methods: [], events: [] },\n snapshot: {},\n policy: { maxPayload: 25 * 1024 * 1024, maxBufferedBytes: 0, tickIntervalMs: 30000 },\n };\n // Extract server info from health events if available\n if (frame.event === 'health' && (frame.payload as any)?.defaultAgentId) {\n syntheticHello.snapshot = frame.payload as Record<string, unknown>;\n }\n this._hello = syntheticHello;\n settle(() => resolve(syntheticHello));\n }\n this.emit(frame.event, frame.payload);\n }\n };\n });\n }\n\n /** Send an RPC request and wait for the response. */\n request<T = unknown>(method: string, params?: unknown, timeoutMs = RPC_TIMEOUT_MS): Promise<T> {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n return Promise.reject(new Error('not connected'));\n }\n\n const id = newRequestId();\n const frame: RequestFrame = { type: 'req', id, method, params };\n\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => {\n this.pending.delete(id);\n reject(new Error(`RPC timeout: ${method} after ${timeoutMs}ms`));\n }, timeoutMs);\n\n this.pending.set(id, {\n resolve: resolve as (v: unknown) => void,\n reject,\n timer,\n });\n\n this.ws!.send(JSON.stringify(frame));\n });\n }\n\n /** Close the connection. */\n close(): void {\n this._connected = false;\n this.ws?.close();\n this.flushPending(new Error('client closed'));\n }\n\n // ─── High-Level RPC Methods ─────────────────────────────\n\n async getStatus(): Promise<GatewayStatus> {\n return this.request<GatewayStatus>('status', {});\n }\n\n async listModels(): Promise<GatewayModel[]> {\n return this.request<GatewayModel[]>('models.list', {});\n }\n\n async listAgents(): Promise<{ defaultId: string; agents: GatewayAgent[] }> {\n return this.request('agents.list', {});\n }\n\n async createAgent(name: string, workspace: string): Promise<{ ok: boolean; agentId: string }> {\n return this.request('agents.create', { name, workspace });\n }\n\n async updateAgent(agentId: string, params: { model?: string; name?: string }): Promise<{ ok: boolean }> {\n return this.request('agents.update', { agentId, ...params });\n }\n\n async deleteAgent(agentId: string): Promise<{ ok: boolean }> {\n return this.request('agents.delete', { agentId });\n }\n\n async listAgentFiles(agentId: string): Promise<GatewayAgentDetail> {\n return this.request('agents.files.list', { agentId });\n }\n\n async getAgentFile(agentId: string, name: string): Promise<{ file: { name: string; content: string } }> {\n return this.request('agents.files.get', { agentId, name });\n }\n\n async setAgentFile(agentId: string, name: string, content: string): Promise<{ ok: boolean }> {\n return this.request('agents.files.set', { agentId, name, content });\n }\n\n // ─── Chat Methods ───────────────────────────────────────\n\n /** Get chat history for a session. */\n async getChatHistory(sessionKey: string, limit = 200): Promise<ChatHistoryResponse> {\n return this.request<ChatHistoryResponse>('chat.history', { sessionKey, limit });\n }\n\n /**\n * Send a chat message. Returns immediately with a runId;\n * the response streams via 'chat' events.\n */\n async sendChatMessage(\n sessionKey: string,\n message: string,\n opts?: { thinking?: string },\n ): Promise<ChatSendResponse> {\n return this.request<ChatSendResponse>('chat.send', {\n sessionKey,\n message,\n deliver: true,\n idempotencyKey: newRequestId(),\n ...opts,\n });\n }\n\n /** Abort a running chat completion. */\n async abortChat(runId: string): Promise<void> {\n await this.request('chat.abort', { runId });\n }\n\n // ─── Skills Methods ─────────────────────────────────────\n\n async getSkillsStatus(): Promise<{ skills: SkillInfo[] }> {\n return this.request('skills.status', {});\n }\n\n async updateSkill(skillKey: string, opts: { apiKey?: string; enabled?: boolean }): Promise<unknown> {\n return this.request('skills.update', { skillKey, ...opts });\n }\n\n // ─── Session Methods ────────────────────────────────────\n\n async listSessions(opts?: { limit?: number }): Promise<unknown> {\n return this.request('sessions.list', opts ?? {});\n }\n\n async patchSession(key: string, patch: { label?: string; thinkingLevel?: string }): Promise<unknown> {\n return this.request('sessions.patch', { key, ...patch });\n }\n\n async deleteSession(key: string): Promise<unknown> {\n return this.request('sessions.delete', { key, deleteTranscript: true });\n }\n\n async resetSession(key: string): Promise<unknown> {\n return this.request('sessions.reset', { key });\n }\n\n // ─── Config Methods ─────────────────────────────────────\n\n async getConfig(): Promise<{ hash: string; config: Record<string, unknown> }> {\n return this.request('config.get', {});\n }\n\n async patchConfig(patch: string, baseHash: string, opts?: { note?: string }): Promise<unknown> {\n return this.request('config.patch', { patch, baseHash, ...opts });\n }\n\n /**\n * Set a specific agent as the default.\n * Fetches the current config, marks the target agent with `default: true`,\n * removes the flag from all other agents, then patches the config.\n */\n async setDefaultAgent(agentId: string): Promise<unknown> {\n const current = await this.getConfig();\n const config = current.config ?? {};\n const agentsSection =\n config.agents && typeof config.agents === 'object' ? (config.agents as Record<string, unknown>) : {};\n const existingList = Array.isArray(agentsSection.list)\n ? (agentsSection.list as Array<Record<string, unknown>>)\n : [];\n\n const updatedList: Array<Record<string, unknown>> = [];\n let found = false;\n\n for (const entry of existingList) {\n const clone = { ...entry };\n if (clone.id === agentId) {\n clone.default = true;\n found = true;\n } else {\n delete clone.default;\n }\n updatedList.push(clone);\n }\n\n if (!found) {\n updatedList.push({\n id: agentId,\n default: true,\n workspace: `/home/node/.openclaw/workspaces/${agentId}`,\n });\n }\n\n const patch = { agents: { ...agentsSection, list: updatedList } };\n return this.patchConfig(JSON.stringify(patch), current.hash, {\n note: `Set default agent to \"${agentId}\"`,\n });\n }\n\n async setLlmKey(provider: string, apiKey: string): Promise<unknown> {\n const envKey = `${provider.toUpperCase()}_API_KEY`;\n const current = await this.getConfig();\n const envObj = (current.config.env as Record<string, unknown>) ?? {};\n const varsObj = (envObj?.vars as Record<string, unknown>) ?? {};\n const merged = {\n ...current.config,\n env: {\n ...envObj,\n vars: {\n ...varsObj,\n [envKey]: apiKey,\n },\n },\n };\n return this.request('config.set', { raw: JSON.stringify(merged), baseHash: current.hash });\n }\n\n // ─── Channel Methods ────────────────────────────────────\n\n async getChannelsStatus(probe = false): Promise<ChannelsStatusResponse> {\n return this.request<ChannelsStatusResponse>('channels.status', { probe });\n }\n\n async connectChannel(channel: string, config: Record<string, unknown>): Promise<unknown> {\n const supportedMethods = this._hello?.features?.methods ?? [];\n\n if (supportedMethods.includes('channels.connect')) {\n return this.request('channels.connect', {\n channel,\n config: { enabled: true, ...config },\n });\n }\n\n return this.mergeAndSetConfig({\n channels: {\n [channel]: { enabled: true, ...config },\n },\n });\n }\n\n async mergeAndSetConfig(patch: Record<string, unknown>): Promise<unknown> {\n const current = await this.getConfig();\n const base = current.config ?? {};\n const merged = deepMerge(base, patch);\n\n const mergedJson = JSON.stringify(merged);\n const baseJson = JSON.stringify(base);\n if (mergedJson === baseJson) return;\n\n return this.request('config.set', { raw: mergedJson, baseHash: current.hash });\n }\n\n async restartGateway(): Promise<unknown> {\n try {\n return await this.request('gateway.restart', {}, 10_000);\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n if (msg.includes('closed') || msg.includes('timeout') || msg.includes('lost')) {\n return { restarting: true };\n }\n throw err;\n }\n }\n\n async logoutChannel(channel: string): Promise<unknown> {\n return this.request('channels.logout', { channel });\n }\n\n async applyConfig(raw: string, baseHash: string, opts?: { note?: string }): Promise<unknown> {\n return this.request('config.set', { raw, baseHash, ...opts });\n }\n\n async webLoginStart(opts: { force?: boolean; verbose?: boolean } = {}): Promise<{\n qrDataUrl?: string;\n pairingCode?: string;\n message?: string;\n }> {\n return this.request('web.login.start', opts);\n }\n\n async webLoginWait(opts: { timeoutMs?: number } = {}): Promise<{\n connected: boolean;\n message?: string;\n }> {\n const clientTimeout = (opts.timeoutMs ?? 120_000) + 10_000;\n return this.request('web.login.wait', opts, clientTimeout);\n }\n\n // ─── Private ────────────────────────────────────────────\n\n private emit(event: string, payload: unknown): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n for (const handler of handlers) {\n try {\n handler(payload);\n } catch (e) {\n console.error(`[GatewayClient] Event handler error for '${event}':`, e);\n }\n }\n }\n }\n\n private flushPending(err: Error): void {\n for (const [, p] of this.pending) {\n clearTimeout(p.timer);\n p.reject(err);\n }\n this.pending.clear();\n }\n}\n"],"names":["uuidv4"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"gatewayClient.js","sources":["../../src/services/gatewayClient.ts"],"sourcesContent":["/**\n * OpenClaw Gateway WebSocket client for yantra-app.\n *\n * Speaks the gateway's protocol v3:\n * 1. Client opens WebSocket to /ws/openclaw-chat (backend proxy)\n * 2. Gateway sends connect.challenge event with nonce\n * 3. Client sends connect request with auth token\n * 4. Gateway replies with hello-ok (available methods, events, snapshot)\n * 5. Client sends RPC requests, gateway replies; chat streams via events\n */\n\nimport { v4 as uuidv4 } from 'uuid';\n\nfunction newRequestId(): string {\n const c = globalThis.crypto as Crypto | undefined;\n if (c?.randomUUID) return c.randomUUID();\n return uuidv4();\n}\n\n// ─── Protocol Constants ─────────────────────────────────────────\n\n/** Gateway 2026.6.x speaks protocol v4; negotiate v3–v4 for older runtimes. */\nconst OPENCLAW_MIN_PROTOCOL_VERSION = 3;\nconst OPENCLAW_PROTOCOL_VERSION = 4;\nconst CONNECT_TIMEOUT_MS = 30_000;\nconst RPC_TIMEOUT_MS = 30_000;\n\n// ─── Protocol Frame Types ───────────────────────────────────────\n\ninterface RequestFrame {\n type: 'req';\n id: string;\n method: string;\n params?: unknown;\n}\n\ninterface ResponseFrame {\n type: 'res';\n id: string;\n ok: boolean;\n payload?: unknown;\n error?: { code: string; message: string; retryable?: boolean };\n}\n\ninterface EventFrame {\n type: 'event';\n event: string;\n payload?: unknown;\n seq?: number;\n}\n\ntype Frame = RequestFrame | ResponseFrame | EventFrame;\n\n// ─── Public Types ───────────────────────────────────────────────\n\nexport interface HelloOk {\n type: 'hello-ok';\n protocol: number;\n server: { version: string; connId: string };\n features: { methods: string[]; events: string[] };\n snapshot: Record<string, unknown>;\n policy: { maxPayload: number; maxBufferedBytes: number; tickIntervalMs: number };\n}\n\nexport interface GatewayModel {\n id: string;\n name: string;\n provider: string;\n available: boolean;\n}\n\nexport interface GatewayAgent {\n id: string;\n name?: string;\n}\n\nexport interface GatewayAgentDetail {\n agentId: string;\n workspace: string;\n files: Array<{ name: string; path: string; missing: boolean; size?: number }>;\n}\n\nexport interface ChatSendResponse {\n runId: string;\n status: 'started' | 'queued';\n}\n\nexport interface ChatStreamEvent {\n runId: string;\n sessionKey: string;\n seq: number;\n state: 'delta' | 'final' | 'aborted' | 'error';\n message?: {\n role: string;\n content: string | Array<{ type: string; text?: string; [k: string]: unknown }>;\n usage?: { inputTokens?: number; outputTokens?: number };\n stopReason?: string;\n };\n errorMessage?: string;\n}\n\nexport interface ChatHistoryResponse {\n sessionKey: string;\n sessionId?: string;\n messages: Array<{\n role: string;\n content: string | Array<{ type: string; text?: string; [k: string]: unknown }>;\n timestamp?: number;\n usage?: { inputTokens?: number; outputTokens?: number };\n }>;\n}\n\nexport interface SkillInfo {\n skillKey: string;\n name: string;\n description?: string;\n eligible: boolean;\n enabled?: boolean;\n missing?: { env?: string[]; binaries?: string[] };\n}\n\nexport interface GatewayStatus {\n healthy: boolean;\n uptime?: number;\n version?: string;\n connId?: string;\n}\n\nexport interface ChannelStatusEntry {\n channel: string;\n accountId?: string;\n configured: boolean;\n connected: boolean;\n enabled: boolean;\n error?: string;\n linked?: boolean;\n running?: boolean;\n lastError?: string;\n [key: string]: unknown;\n}\n\nexport interface ChannelsStatusResponse {\n channels: ChannelStatusEntry[];\n}\n\n// ─── Pending Request Tracker ────────────────────────────────────\n\ninterface Pending {\n resolve: (value: unknown) => void;\n reject: (err: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n}\n\n// ─── Helpers ────────────────────────────────────────────────────\n\nfunction deepMerge(target: Record<string, unknown>, source: Record<string, unknown>): Record<string, unknown> {\n const result: Record<string, unknown> = { ...target };\n for (const key of Object.keys(source)) {\n const sv = source[key];\n const tv = result[key];\n if (sv && typeof sv === 'object' && !Array.isArray(sv) && tv && typeof tv === 'object' && !Array.isArray(tv)) {\n result[key] = deepMerge(tv as Record<string, unknown>, sv as Record<string, unknown>);\n } else {\n result[key] = sv;\n }\n }\n return result;\n}\n\n// ─── GatewayClient ──────────────────────────────────────────────\n\n/**\n * WebSocket client for communicating with an OpenClaw gateway\n * through the backend chat proxy (/ws/openclaw-chat).\n */\nexport class GatewayClient {\n private ws: WebSocket | null = null;\n\n private pending = new Map<string, Pending>();\n\n private _connected = false;\n\n private _hello: HelloOk | null = null;\n\n private _eventHandlers = new Map<string, Set<(payload: unknown) => void>>();\n\n private readonly url: string;\n\n private readonly token: string;\n\n private readonly wsProtocol?: string;\n\n constructor(url: string, token: string, wsProtocol?: string) {\n this.url = url;\n this.token = token;\n this.wsProtocol = wsProtocol;\n }\n\n get connected(): boolean {\n return this._connected;\n }\n\n get hello(): HelloOk | null {\n return this._hello;\n }\n\n /** Register an event handler for gateway push events. */\n on(event: string, handler: (payload: unknown) => void): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n }\n\n /** Remove an event handler. */\n off(event: string, handler: (payload: unknown) => void): void {\n this._eventHandlers.get(event)?.delete(handler);\n }\n\n /** Connect to the gateway and authenticate. Resolves with HelloOk on success. */\n connect(): Promise<HelloOk> {\n return new Promise((resolve, reject) => {\n let settled = false;\n let timer: ReturnType<typeof setTimeout>;\n let sawChallenge = false;\n const settle = (fn: () => void) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n fn();\n };\n\n timer = setTimeout(\n () => settle(() => reject(new Error(`connect timeout after ${CONNECT_TIMEOUT_MS}ms`))),\n CONNECT_TIMEOUT_MS,\n );\n\n this.ws = this.wsProtocol ? new WebSocket(this.url, this.wsProtocol) : new WebSocket(this.url);\n\n this.ws.onerror = (ev) => {\n console.error(`[GatewayClient] WS error: url=${this.url}`, ev);\n settle(() => reject(new Error('WebSocket connection error')));\n };\n\n this.ws.onclose = (ev) => {\n this._connected = false;\n this.flushPending(new Error('connection closed'));\n const detail = ev.reason ? ` reason=\"${ev.reason}\"` : '';\n console.warn(\n `[GatewayClient] WS closed: code=${ev.code}${detail} url=${this.url} challengeReceived=${sawChallenge}`,\n );\n settle(() => reject(new Error(`connection closed before handshake (code=${ev.code})`)));\n this.emit('disconnect', { code: ev.code, reason: ev.reason });\n };\n\n this.ws.onmessage = (event) => {\n const raw = typeof event.data === 'string' ? event.data : String(event.data);\n let frame: Frame;\n try {\n frame = JSON.parse(raw);\n } catch {\n return;\n }\n\n // Handle connect.challenge → send connect request (fresh connection)\n if (frame.type === 'event' && frame.event === 'connect.challenge') {\n sawChallenge = true;\n this.request<HelloOk>('connect', {\n minProtocol: OPENCLAW_MIN_PROTOCOL_VERSION,\n maxProtocol: OPENCLAW_PROTOCOL_VERSION,\n client: {\n id: 'openclaw-control-ui',\n version: '1.0.0',\n platform: 'react-native',\n mode: 'ui',\n displayName: 'Yantra App',\n },\n role: 'operator',\n scopes: ['operator.admin', 'operator.read', 'operator.write'],\n caps: [],\n auth: { token: this.token },\n })\n .then((hello) => {\n this._connected = true;\n this._hello = hello;\n settle(() => resolve(hello));\n })\n .catch((err) => settle(() => reject(err)));\n return;\n }\n\n // Handle response frames\n if (frame.type === 'res') {\n const p = this.pending.get(frame.id);\n if (p) {\n clearTimeout(p.timer);\n this.pending.delete(frame.id);\n if (frame.ok) {\n p.resolve(frame.payload);\n } else {\n p.reject(new Error(frame.error?.message ?? 'RPC error'));\n }\n }\n return;\n }\n\n // Handle event frames\n if (frame.type === 'event') {\n // Pooled/pre-authenticated connection: receiving events without\n // a prior connect.challenge means the proxy reused an already-\n // authenticated server→gateway WS. Consider ourselves connected.\n if (!sawChallenge && !this._connected) {\n this._connected = true;\n const syntheticHello: HelloOk = {\n type: 'hello-ok',\n protocol: OPENCLAW_PROTOCOL_VERSION,\n server: { version: 'unknown', connId: 'pooled' },\n features: { methods: [], events: [] },\n snapshot: {},\n policy: { maxPayload: 25 * 1024 * 1024, maxBufferedBytes: 0, tickIntervalMs: 30000 },\n };\n // Extract server info from health events if available\n if (frame.event === 'health' && (frame.payload as any)?.defaultAgentId) {\n syntheticHello.snapshot = frame.payload as Record<string, unknown>;\n }\n this._hello = syntheticHello;\n settle(() => resolve(syntheticHello));\n }\n this.emit(frame.event, frame.payload);\n }\n };\n });\n }\n\n /** Send an RPC request and wait for the response. */\n request<T = unknown>(method: string, params?: unknown, timeoutMs = RPC_TIMEOUT_MS): Promise<T> {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n return Promise.reject(new Error('not connected'));\n }\n\n const id = newRequestId();\n const frame: RequestFrame = { type: 'req', id, method, params };\n\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => {\n this.pending.delete(id);\n reject(new Error(`RPC timeout: ${method} after ${timeoutMs}ms`));\n }, timeoutMs);\n\n this.pending.set(id, {\n resolve: resolve as (v: unknown) => void,\n reject,\n timer,\n });\n\n this.ws!.send(JSON.stringify(frame));\n });\n }\n\n /** Close the connection. */\n close(): void {\n this._connected = false;\n this.ws?.close();\n this.flushPending(new Error('client closed'));\n }\n\n // ─── High-Level RPC Methods ─────────────────────────────\n\n async getStatus(): Promise<GatewayStatus> {\n return this.request<GatewayStatus>('status', {});\n }\n\n async listModels(): Promise<GatewayModel[]> {\n return this.request<GatewayModel[]>('models.list', {});\n }\n\n async listAgents(): Promise<{ defaultId: string; agents: GatewayAgent[] }> {\n return this.request('agents.list', {});\n }\n\n async createAgent(name: string, workspace: string): Promise<{ ok: boolean; agentId: string }> {\n return this.request('agents.create', { name, workspace });\n }\n\n async updateAgent(agentId: string, params: { model?: string; name?: string }): Promise<{ ok: boolean }> {\n return this.request('agents.update', { agentId, ...params });\n }\n\n async deleteAgent(agentId: string): Promise<{ ok: boolean }> {\n return this.request('agents.delete', { agentId });\n }\n\n async listAgentFiles(agentId: string): Promise<GatewayAgentDetail> {\n return this.request('agents.files.list', { agentId });\n }\n\n async getAgentFile(agentId: string, name: string): Promise<{ file: { name: string; content: string } }> {\n return this.request('agents.files.get', { agentId, name });\n }\n\n async setAgentFile(agentId: string, name: string, content: string): Promise<{ ok: boolean }> {\n return this.request('agents.files.set', { agentId, name, content });\n }\n\n // ─── Chat Methods ───────────────────────────────────────\n\n /** Get chat history for a session. */\n async getChatHistory(sessionKey: string, limit = 200): Promise<ChatHistoryResponse> {\n return this.request<ChatHistoryResponse>('chat.history', { sessionKey, limit });\n }\n\n /**\n * Send a chat message. Returns immediately with a runId;\n * the response streams via 'chat' events.\n */\n async sendChatMessage(\n sessionKey: string,\n message: string,\n opts?: { thinking?: string },\n ): Promise<ChatSendResponse> {\n return this.request<ChatSendResponse>('chat.send', {\n sessionKey,\n message,\n deliver: true,\n idempotencyKey: newRequestId(),\n ...opts,\n });\n }\n\n /** Abort a running chat completion. */\n async abortChat(runId: string): Promise<void> {\n await this.request('chat.abort', { runId });\n }\n\n // ─── Skills Methods ─────────────────────────────────────\n\n async getSkillsStatus(): Promise<{ skills: SkillInfo[] }> {\n return this.request('skills.status', {});\n }\n\n async updateSkill(skillKey: string, opts: { apiKey?: string; enabled?: boolean }): Promise<unknown> {\n return this.request('skills.update', { skillKey, ...opts });\n }\n\n // ─── Session Methods ────────────────────────────────────\n\n async listSessions(opts?: { limit?: number }): Promise<unknown> {\n return this.request('sessions.list', opts ?? {});\n }\n\n async patchSession(key: string, patch: { label?: string; thinkingLevel?: string }): Promise<unknown> {\n return this.request('sessions.patch', { key, ...patch });\n }\n\n async deleteSession(key: string): Promise<unknown> {\n return this.request('sessions.delete', { key, deleteTranscript: true });\n }\n\n async resetSession(key: string): Promise<unknown> {\n return this.request('sessions.reset', { key });\n }\n\n // ─── Config Methods ─────────────────────────────────────\n\n async getConfig(): Promise<{ hash: string; config: Record<string, unknown> }> {\n return this.request('config.get', {});\n }\n\n async patchConfig(patch: string, baseHash: string, opts?: { note?: string }): Promise<unknown> {\n return this.request('config.patch', { patch, baseHash, ...opts });\n }\n\n /**\n * Set a specific agent as the default.\n * Fetches the current config, marks the target agent with `default: true`,\n * removes the flag from all other agents, then patches the config.\n */\n async setDefaultAgent(agentId: string): Promise<unknown> {\n const current = await this.getConfig();\n const config = current.config ?? {};\n const agentsSection =\n config.agents && typeof config.agents === 'object' ? (config.agents as Record<string, unknown>) : {};\n const existingList = Array.isArray(agentsSection.list)\n ? (agentsSection.list as Array<Record<string, unknown>>)\n : [];\n\n const updatedList: Array<Record<string, unknown>> = [];\n let found = false;\n\n for (const entry of existingList) {\n const clone = { ...entry };\n if (clone.id === agentId) {\n clone.default = true;\n found = true;\n } else {\n delete clone.default;\n }\n updatedList.push(clone);\n }\n\n if (!found) {\n updatedList.push({\n id: agentId,\n default: true,\n workspace: `/home/node/.openclaw/workspaces/${agentId}`,\n });\n }\n\n const patch = { agents: { ...agentsSection, list: updatedList } };\n return this.patchConfig(JSON.stringify(patch), current.hash, {\n note: `Set default agent to \"${agentId}\"`,\n });\n }\n\n async setLlmKey(provider: string, apiKey: string): Promise<unknown> {\n const envKey = `${provider.toUpperCase()}_API_KEY`;\n const current = await this.getConfig();\n const envObj = (current.config.env as Record<string, unknown>) ?? {};\n const varsObj = (envObj?.vars as Record<string, unknown>) ?? {};\n const merged = {\n ...current.config,\n env: {\n ...envObj,\n vars: {\n ...varsObj,\n [envKey]: apiKey,\n },\n },\n };\n return this.request('config.set', { raw: JSON.stringify(merged), baseHash: current.hash });\n }\n\n // ─── Channel Methods ────────────────────────────────────\n\n async getChannelsStatus(probe = false): Promise<ChannelsStatusResponse> {\n return this.request<ChannelsStatusResponse>('channels.status', { probe });\n }\n\n async connectChannel(channel: string, config: Record<string, unknown>): Promise<unknown> {\n const supportedMethods = this._hello?.features?.methods ?? [];\n\n if (supportedMethods.includes('channels.connect')) {\n return this.request('channels.connect', {\n channel,\n config: { enabled: true, ...config },\n });\n }\n\n return this.mergeAndSetConfig({\n channels: {\n [channel]: { enabled: true, ...config },\n },\n });\n }\n\n async mergeAndSetConfig(patch: Record<string, unknown>): Promise<unknown> {\n const current = await this.getConfig();\n const base = current.config ?? {};\n const merged = deepMerge(base, patch);\n\n const mergedJson = JSON.stringify(merged);\n const baseJson = JSON.stringify(base);\n if (mergedJson === baseJson) return;\n\n return this.request('config.set', { raw: mergedJson, baseHash: current.hash });\n }\n\n async restartGateway(): Promise<unknown> {\n try {\n return await this.request('gateway.restart', {}, 10_000);\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n if (msg.includes('closed') || msg.includes('timeout') || msg.includes('lost')) {\n return { restarting: true };\n }\n throw err;\n }\n }\n\n async logoutChannel(channel: string): Promise<unknown> {\n return this.request('channels.logout', { channel });\n }\n\n async applyConfig(raw: string, baseHash: string, opts?: { note?: string }): Promise<unknown> {\n return this.request('config.set', { raw, baseHash, ...opts });\n }\n\n async webLoginStart(opts: { force?: boolean; verbose?: boolean } = {}): Promise<{\n qrDataUrl?: string;\n pairingCode?: string;\n message?: string;\n }> {\n return this.request('web.login.start', opts);\n }\n\n async webLoginWait(opts: { timeoutMs?: number } = {}): Promise<{\n connected: boolean;\n message?: string;\n }> {\n const clientTimeout = (opts.timeoutMs ?? 120_000) + 10_000;\n return this.request('web.login.wait', opts, clientTimeout);\n }\n\n // ─── Private ────────────────────────────────────────────\n\n private emit(event: string, payload: unknown): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n for (const handler of handlers) {\n try {\n handler(payload);\n } catch (e) {\n console.error(`[GatewayClient] Event handler error for '${event}':`, e);\n }\n }\n }\n }\n\n private flushPending(err: Error): void {\n for (const [, p] of this.pending) {\n clearTimeout(p.timer);\n p.reject(err);\n }\n this.pending.clear();\n }\n}\n"],"names":["uuidv4"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adminide-stack/yantra-mobile",
|
|
3
|
-
"version": "12.0.31-alpha.
|
|
3
|
+
"version": "12.0.31-alpha.71",
|
|
4
4
|
"description": "Sample core for higher packages to depend on",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"author": "CDMBase LLC",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"uuid": "^9.0.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"common": "12.0.31-alpha.
|
|
28
|
+
"common": "12.0.31-alpha.70"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
31
|
"@admin-layout/gluestack-ui-mobile": "*",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"@expo/vector-icons": "*",
|
|
41
41
|
"@messenger-box/platform-mobile": "*",
|
|
42
42
|
"@react-native-async-storage/async-storage": "*",
|
|
43
|
-
"common": "12.0.31-alpha.
|
|
43
|
+
"common": "12.0.31-alpha.70",
|
|
44
44
|
"lodash": "*"
|
|
45
45
|
},
|
|
46
46
|
"publishConfig": {
|
|
@@ -49,5 +49,5 @@
|
|
|
49
49
|
"typescript": {
|
|
50
50
|
"definition": "lib/index.d.ts"
|
|
51
51
|
},
|
|
52
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "526a612bb1471966736480bc79a346472f72e130"
|
|
53
53
|
}
|