@epam/ai-dial-chat-hooks 1.1.0-dev.459 → 1.1.0-dev.467
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/conversation/conversation-transfer/build-upload-path.js +3 -0
- package/conversation/useAttachmentUpload/useAttachmentUpload.js +44 -27
- package/conversation/useConversationImport/useConversationImport.js +36 -36
- package/conversation.d.ts +2 -1
- package/index.d.ts +16 -5
- package/mcp-apps/useMcpAppHostContext/useMcpAppHostContext.js +4 -2
- package/mcp-apps/useOpenMcpAppCanvas/useOpenMcpAppCanvas.js +14 -13
- package/mcp-apps.d.ts +12 -2
- package/package.json +19 -19
- package/utils.d.ts +2 -2
|
@@ -1,38 +1,55 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { formatDateYM as e } from "../conversation-transfer/date.js";
|
|
2
|
+
import { sanitizeFileName as t } from "../../files/file-name.js";
|
|
3
|
+
import { createUploadPathAllocator as n } from "../conversation-transfer/build-upload-path.js";
|
|
4
|
+
import { AttachmentErrorReason as r } from "@epam/ai-dial-chat-shared";
|
|
5
|
+
import { useCallback as i, useRef as a } from "react";
|
|
4
6
|
//#region src/conversation/useAttachmentUpload/useAttachmentUpload.ts
|
|
5
|
-
var
|
|
6
|
-
let
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
var o = 700, s = 5, c = (e) => t(e.split("/").filter(Boolean).pop() ?? "file").replace(/\.\.+/g, ".").replace(/^\.+/, "") || "file", l = (e) => typeof e == "object" && !!e && "response" in e && e.response?.status === 409, u = ({ filesApi: t, bucket: u, onNetworkError: d, debounceMs: f = o }) => {
|
|
8
|
+
let p = a([]), m = a(null), h = a(null), g = i((t, r) => {
|
|
9
|
+
let i = `${t}|${e(r)}`;
|
|
10
|
+
return h.current?.key !== i && (h.current = {
|
|
11
|
+
key: i,
|
|
12
|
+
allocator: n({ date: r })
|
|
13
|
+
}), h.current.allocator;
|
|
14
|
+
}, []);
|
|
15
|
+
return { handleUploadAttachment: i(async (e) => {
|
|
16
|
+
if (!u) throw Error("User bucket is not available");
|
|
17
|
+
let n = c(e.name), i = g(u, /* @__PURE__ */ new Date()), a = i.allocate(n);
|
|
18
|
+
for (let o = 0;; o += 1) try {
|
|
19
|
+
let n = a.isRenamed ? new File([e.file], a.fileName, { type: e.file.type }) : e.file;
|
|
11
20
|
return {
|
|
12
|
-
url: (await
|
|
13
|
-
bucket:
|
|
14
|
-
path:
|
|
15
|
-
file: n
|
|
21
|
+
url: (await t.uploadFile({
|
|
22
|
+
bucket: u,
|
|
23
|
+
path: a.path,
|
|
24
|
+
file: n,
|
|
25
|
+
uploadMode: "create-only"
|
|
16
26
|
})).url,
|
|
17
|
-
name:
|
|
27
|
+
name: a.fileName
|
|
18
28
|
};
|
|
19
|
-
} catch (
|
|
29
|
+
} catch (t) {
|
|
30
|
+
if (l(t)) {
|
|
31
|
+
if (i.markTaken(a.fileName), o < s) {
|
|
32
|
+
a = i.allocate(n);
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
} else i.release(a.fileName);
|
|
20
36
|
if (!navigator.onLine) {
|
|
21
|
-
|
|
22
|
-
let e =
|
|
23
|
-
|
|
24
|
-
},
|
|
25
|
-
let
|
|
26
|
-
throw
|
|
37
|
+
p.current.push(e.name), m.current != null && clearTimeout(m.current), m.current = setTimeout(() => {
|
|
38
|
+
let e = p.current.splice(0);
|
|
39
|
+
d?.(e), m.current = null;
|
|
40
|
+
}, f);
|
|
41
|
+
let n = t instanceof Error ? t : /* @__PURE__ */ Error("Network upload failed");
|
|
42
|
+
throw n.errorReason = r.Network, n;
|
|
27
43
|
}
|
|
28
|
-
throw
|
|
44
|
+
throw t;
|
|
29
45
|
}
|
|
30
46
|
}, [
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
47
|
+
u,
|
|
48
|
+
f,
|
|
49
|
+
t,
|
|
50
|
+
g,
|
|
51
|
+
d
|
|
35
52
|
]) };
|
|
36
53
|
};
|
|
37
54
|
//#endregion
|
|
38
|
-
export {
|
|
55
|
+
export { u as useAttachmentUpload };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { formatDateYM as e } from "../conversation-transfer/date.js";
|
|
2
2
|
import { ConversationTransferWarningCode as t } from "../conversation-transfer/types.js";
|
|
3
3
|
import { UnsupportedImportFormatError as n, getFolderBreadcrumb as r, parseImportEnvelope as i, planAttachmentUploads as a, rebaseConversationId as o, rewriteAttachmentUrls as s } from "../conversation-transfer/import-conversation.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
4
|
+
import { createUploadPathAllocator as c } from "../conversation-transfer/build-upload-path.js";
|
|
5
|
+
import { runWithConcurrency as l } from "../conversation-transfer/async.js";
|
|
6
|
+
import { ConversationTransferKind as u, ConversationTransferPhase as d, buildTransferProgress as f } from "../conversation-transfer/progress.js";
|
|
7
|
+
import { useConversationTransferQueue as p } from "../conversation-transfer/queue.js";
|
|
8
8
|
import { parseDialArchive as m } from "../conversation-transfer/zip-import.js";
|
|
9
9
|
import { ConversationTransferErrorCode as h, ConversationTransferSubjectKind as g, ConversationTransferUnitKind as _, generateUUID as v } from "@epam/ai-dial-chat-shared";
|
|
10
10
|
import { useCallback as y } from "react";
|
|
@@ -26,9 +26,9 @@ var b = 5, x = 5, S = (e) => /\.(dial|zip)$/i.test(e.name), C = (e) => new Promi
|
|
|
26
26
|
attachments: /* @__PURE__ */ new Map(),
|
|
27
27
|
isArchive: !1
|
|
28
28
|
};
|
|
29
|
-
}, T = async (e, t, n, r, i, o, s,
|
|
30
|
-
let { plan: u, skippedNames: d } = a(e, t, r), f = !1, p = await
|
|
31
|
-
if (
|
|
29
|
+
}, T = async (e, t, n, r, i, o, s, c) => {
|
|
30
|
+
let { plan: u, skippedNames: d } = a(e, t, r), f = !1, p = await l(u, b, async (e) => {
|
|
31
|
+
if (c.aborted || f) return;
|
|
32
32
|
let t = e.allocated;
|
|
33
33
|
for (let a = 0; a <= x; a += 1) try {
|
|
34
34
|
let r = new File([new Uint8Array(e.bytes)], t.fileName), a = await i.uploadFile({
|
|
@@ -36,7 +36,7 @@ var b = 5, x = 5, S = (e) => /\.(dial|zip)$/i.test(e.name), C = (e) => new Promi
|
|
|
36
36
|
path: t.path,
|
|
37
37
|
file: r,
|
|
38
38
|
uploadMode: "create-only"
|
|
39
|
-
}, { signal:
|
|
39
|
+
}, { signal: c });
|
|
40
40
|
return s(), {
|
|
41
41
|
kind: "uploaded",
|
|
42
42
|
oldFileId: e.fileId,
|
|
@@ -44,7 +44,7 @@ var b = 5, x = 5, S = (e) => /\.(dial|zip)$/i.test(e.name), C = (e) => new Promi
|
|
|
44
44
|
newTitle: t.isRenamed ? t.fileName : void 0
|
|
45
45
|
};
|
|
46
46
|
} catch (n) {
|
|
47
|
-
if (
|
|
47
|
+
if (c.aborted) return;
|
|
48
48
|
if (o(n)) {
|
|
49
49
|
f = !0;
|
|
50
50
|
return;
|
|
@@ -66,22 +66,22 @@ var b = 5, x = 5, S = (e) => /\.(dial|zip)$/i.test(e.name), C = (e) => new Promi
|
|
|
66
66
|
}) : h.push(e.name);
|
|
67
67
|
return {
|
|
68
68
|
targetMap: m,
|
|
69
|
-
skippedNames:
|
|
70
|
-
isUnauthorized: !
|
|
69
|
+
skippedNames: c.aborted || f ? [] : h,
|
|
70
|
+
isUnauthorized: !c.aborted && f
|
|
71
71
|
};
|
|
72
|
-
}, E = ({ conversationsApi: i, filesApi: a, bucket:
|
|
73
|
-
let D =
|
|
74
|
-
if (!
|
|
72
|
+
}, E = ({ conversationsApi: i, filesApi: a, bucket: l, onImported: m, classifyTransferError: b = () => ({}), resolveErrorTraceId: x = async () => void 0, onSuccess: S, onWarning: C, onError: E }) => {
|
|
73
|
+
let D = p(), O = y(async (n, r, p) => {
|
|
74
|
+
if (!l) {
|
|
75
75
|
E?.({
|
|
76
76
|
jobId: n,
|
|
77
77
|
code: h.MissingBucket
|
|
78
78
|
}), D.failJob(n, h.MissingBucket);
|
|
79
79
|
return;
|
|
80
80
|
}
|
|
81
|
-
let g =
|
|
82
|
-
y += 1, D.setJobProgress(n,
|
|
81
|
+
let g = u.Import, v = r.attachments.size, y = 0, w = () => {
|
|
82
|
+
y += 1, D.setJobProgress(n, f({
|
|
83
83
|
kind: g,
|
|
84
|
-
phase:
|
|
84
|
+
phase: d.Transfer,
|
|
85
85
|
completed: y,
|
|
86
86
|
total: v
|
|
87
87
|
}, {
|
|
@@ -90,9 +90,9 @@ var b = 5, x = 5, S = (e) => /\.(dial|zip)$/i.test(e.name), C = (e) => new Promi
|
|
|
90
90
|
kind: _.Attachment
|
|
91
91
|
}));
|
|
92
92
|
}, O = (e) => {
|
|
93
|
-
D.setJobProgress(n,
|
|
93
|
+
D.setJobProgress(n, f({
|
|
94
94
|
kind: g,
|
|
95
|
-
phase:
|
|
95
|
+
phase: d.Finalize,
|
|
96
96
|
completed: e,
|
|
97
97
|
total: r.history.length
|
|
98
98
|
}, {
|
|
@@ -105,11 +105,11 @@ var b = 5, x = 5, S = (e) => /\.(dial|zip)$/i.test(e.name), C = (e) => new Promi
|
|
|
105
105
|
let t = `uploads/${e(P)}`, r = [];
|
|
106
106
|
try {
|
|
107
107
|
r = (await a.listFiles({
|
|
108
|
-
bucket:
|
|
108
|
+
bucket: l,
|
|
109
109
|
path: t
|
|
110
|
-
}, { signal:
|
|
110
|
+
}, { signal: p })).items.map((e) => e.name);
|
|
111
111
|
} catch (e) {
|
|
112
|
-
if (
|
|
112
|
+
if (p.aborted) return;
|
|
113
113
|
if (F(e)) {
|
|
114
114
|
E?.({
|
|
115
115
|
jobId: n,
|
|
@@ -119,26 +119,26 @@ var b = 5, x = 5, S = (e) => /\.(dial|zip)$/i.test(e.name), C = (e) => new Promi
|
|
|
119
119
|
}
|
|
120
120
|
console.error("Failed to list the upload folder for attachment name disambiguation", e);
|
|
121
121
|
}
|
|
122
|
-
I =
|
|
122
|
+
I = c({
|
|
123
123
|
date: P,
|
|
124
124
|
existingNames: r
|
|
125
125
|
});
|
|
126
126
|
}
|
|
127
|
-
D.setJobProgress(n,
|
|
127
|
+
D.setJobProgress(n, f({
|
|
128
128
|
kind: g,
|
|
129
|
-
phase:
|
|
130
|
-
})), v === 0 && D.setJobProgress(n,
|
|
129
|
+
phase: d.Prepare
|
|
130
|
+
})), v === 0 && D.setJobProgress(n, f({
|
|
131
131
|
kind: g,
|
|
132
|
-
phase:
|
|
132
|
+
phase: d.Transfer
|
|
133
133
|
}));
|
|
134
134
|
for (let e of r.history) {
|
|
135
|
-
if (
|
|
135
|
+
if (p.aborted) return;
|
|
136
136
|
if (M) break;
|
|
137
137
|
try {
|
|
138
138
|
let t = /* @__PURE__ */ new Map();
|
|
139
139
|
if (r.isArchive && I) {
|
|
140
|
-
let n = await T(e, r.attachments,
|
|
141
|
-
if (
|
|
140
|
+
let n = await T(e, r.attachments, l, I, a, F, w, p);
|
|
141
|
+
if (p.aborted) return;
|
|
142
142
|
if (n.isUnauthorized) {
|
|
143
143
|
M = !0;
|
|
144
144
|
break;
|
|
@@ -146,17 +146,17 @@ var b = 5, x = 5, S = (e) => /\.(dial|zip)$/i.test(e.name), C = (e) => new Promi
|
|
|
146
146
|
for (let e of n.skippedNames) j.add(e);
|
|
147
147
|
t = n.targetMap;
|
|
148
148
|
}
|
|
149
|
-
let { conversation: n, subPath:
|
|
149
|
+
let { conversation: n, subPath: c } = o(s(e, t), l);
|
|
150
150
|
if (await i.saveConversation({
|
|
151
|
-
path:
|
|
151
|
+
path: c,
|
|
152
152
|
saveConversationBodyDto: { conversation: {
|
|
153
153
|
...n,
|
|
154
154
|
llmNamingDone: !0
|
|
155
155
|
} }
|
|
156
|
-
}, { signal:
|
|
156
|
+
}, { signal: p }), p.aborted) return;
|
|
157
157
|
k.push(n.name);
|
|
158
158
|
} catch (t) {
|
|
159
|
-
if (
|
|
159
|
+
if (p.aborted) return;
|
|
160
160
|
if (F(t)) {
|
|
161
161
|
M = !0;
|
|
162
162
|
break;
|
|
@@ -165,7 +165,7 @@ var b = 5, x = 5, S = (e) => /\.(dial|zip)$/i.test(e.name), C = (e) => new Promi
|
|
|
165
165
|
}
|
|
166
166
|
O(k.length + A.length);
|
|
167
167
|
}
|
|
168
|
-
if (!
|
|
168
|
+
if (!p.aborted) {
|
|
169
169
|
if (M) {
|
|
170
170
|
E?.({
|
|
171
171
|
jobId: n,
|
|
@@ -194,7 +194,7 @@ var b = 5, x = 5, S = (e) => /\.(dial|zip)$/i.test(e.name), C = (e) => new Promi
|
|
|
194
194
|
}), A.length > 0 ? D.failJob(n, h.Unknown) : j.size > 0 ? D.warnJob(n, t.AttachmentSkipped) : D.succeedJob(n);
|
|
195
195
|
}
|
|
196
196
|
}, [
|
|
197
|
-
|
|
197
|
+
l,
|
|
198
198
|
b,
|
|
199
199
|
i,
|
|
200
200
|
a,
|
package/conversation.d.ts
CHANGED
|
@@ -690,7 +690,8 @@ export declare const useAsyncConfirmDialog: <T>() => AsyncConfirmDialogControls<
|
|
|
690
690
|
|
|
691
691
|
/**
|
|
692
692
|
* Uploads an attachment's file to DIAL Core storage against an
|
|
693
|
-
* already-configured `FilesApi` instance,
|
|
693
|
+
* already-configured `FilesApi` instance, giving every upload a collision-free
|
|
694
|
+
* path so no attachment overwrites another, and coalescing a burst of
|
|
694
695
|
* offline/network upload failures into a single debounced callback rather
|
|
695
696
|
* than firing one notification per failed file.
|
|
696
697
|
*/
|
package/index.d.ts
CHANGED
|
@@ -34,8 +34,8 @@ import type { CustomVisualizerDataLayout } from '@epam/ai-dial-chat-shared';
|
|
|
34
34
|
import { DeleteFilesResponseDto } from '@epam/ai-dial-chat-api-client';
|
|
35
35
|
import { DeleteItemDto } from '@epam/ai-dial-chat-api-client';
|
|
36
36
|
import { DeploymentConfigurationSchema } from '@epam/ai-dial-chat-shared';
|
|
37
|
-
import { DeploymentCreationFormLocaleEntry } from '@epam/ai-dial-
|
|
38
|
-
import { DeploymentCreationFormLocaleOption } from '@epam/ai-dial-
|
|
37
|
+
import { DeploymentCreationFormLocaleEntry } from '@epam/ai-dial-builder-form';
|
|
38
|
+
import { DeploymentCreationFormLocaleOption } from '@epam/ai-dial-builder-form';
|
|
39
39
|
import { DeploymentDetailsDto } from '@epam/ai-dial-chat-api-client';
|
|
40
40
|
import { DeploymentFeatures } from '@epam/ai-dial-chat-shared';
|
|
41
41
|
import { DeploymentItemDto } from '@epam/ai-dial-chat-api-client';
|
|
@@ -2186,6 +2186,9 @@ declare interface MarkdownCanvasContent {
|
|
|
2186
2186
|
text: string;
|
|
2187
2187
|
}
|
|
2188
2188
|
|
|
2189
|
+
/** Display mode an MCP App can ask the host to switch to via `ui/request-display-mode` — the MCP UI protocol's `inline`/`fullscreen`/`pip` union. */
|
|
2190
|
+
declare type McpAppDisplayMode = NonNullable<McpUiHostContext['displayMode']>;
|
|
2191
|
+
|
|
2189
2192
|
/**
|
|
2190
2193
|
* Dependencies the host must inject into `useMcpAppInlinePreview` /
|
|
2191
2194
|
* `McpAppInlinePreview` — everything that requires host context (theming,
|
|
@@ -2213,6 +2216,12 @@ export declare interface McpAppHostContextParams {
|
|
|
2213
2216
|
locale: string;
|
|
2214
2217
|
/** Operator-configured MCP App user-agent override. Defaults to `'ai-dial-chat'`. */
|
|
2215
2218
|
mcpAppUserAgent?: string;
|
|
2219
|
+
/**
|
|
2220
|
+
* Display modes the host can switch an app between via
|
|
2221
|
+
* `ui/request-display-mode`. Defaults to `['inline', 'fullscreen']` — the
|
|
2222
|
+
* compact inline preview and the full-width canvas.
|
|
2223
|
+
*/
|
|
2224
|
+
availableDisplayModes?: McpAppDisplayMode[];
|
|
2216
2225
|
}
|
|
2217
2226
|
|
|
2218
2227
|
/** Thrown by `McpAppsApiClient.fetchResourceHtml` on a non-OK response, carrying the HTTP status so callers can distinguish `403` (forbidden) from any other failure. */
|
|
@@ -3853,7 +3862,8 @@ export declare interface UseAttachmentActionResult {
|
|
|
3853
3862
|
|
|
3854
3863
|
/**
|
|
3855
3864
|
* Uploads an attachment's file to DIAL Core storage against an
|
|
3856
|
-
* already-configured `FilesApi` instance,
|
|
3865
|
+
* already-configured `FilesApi` instance, giving every upload a collision-free
|
|
3866
|
+
* path so no attachment overwrites another, and coalescing a burst of
|
|
3857
3867
|
* offline/network upload failures into a single debounced callback rather
|
|
3858
3868
|
* than firing one notification per failed file.
|
|
3859
3869
|
*/
|
|
@@ -4941,9 +4951,10 @@ export declare const useMcpAppHostAdapter: (displayMode: "inline" | "fullscreen"
|
|
|
4941
4951
|
* `ui/initialize` handshake, shared by every place that mounts an app —
|
|
4942
4952
|
* a full-width attachment canvas (`displayMode: 'fullscreen'`) and a compact
|
|
4943
4953
|
* inline preview under a message (`displayMode: 'inline'`) — so the app can
|
|
4944
|
-
* size/style itself differently for each
|
|
4954
|
+
* size/style itself differently for each, and knows (via
|
|
4955
|
+
* `availableDisplayModes`) which surfaces it may ask the host to switch to.
|
|
4945
4956
|
*/
|
|
4946
|
-
export declare const useMcpAppHostContext: (displayMode: "inline" | "fullscreen", { theme, mcpAppTheme, locale, mcpAppUserAgent }: McpAppHostContextParams) => McpUiHostContext;
|
|
4957
|
+
export declare const useMcpAppHostContext: (displayMode: "inline" | "fullscreen", { theme, mcpAppTheme, locale, mcpAppUserAgent, availableDisplayModes, }: McpAppHostContextParams) => McpUiHostContext;
|
|
4947
4958
|
|
|
4948
4959
|
/**
|
|
4949
4960
|
* Discovers MCP Apps-capable tools available to the current conversation, merging two
|
|
@@ -7,20 +7,22 @@ var t = /* @__PURE__ */ "--color-background-primary.--color-background-secondary
|
|
|
7
7
|
t && (n[r] = t);
|
|
8
8
|
}
|
|
9
9
|
return n;
|
|
10
|
-
}, r = (t, { theme: r, mcpAppTheme: i, locale: a, mcpAppUserAgent: o }) => e(() => ({
|
|
10
|
+
}, r = (t, { theme: r, mcpAppTheme: i, locale: a, mcpAppUserAgent: o, availableDisplayModes: s }) => e(() => ({
|
|
11
11
|
theme: i ?? r,
|
|
12
12
|
locale: a,
|
|
13
13
|
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
14
14
|
userAgent: o ?? "ai-dial-chat",
|
|
15
15
|
platform: "web",
|
|
16
16
|
displayMode: t,
|
|
17
|
+
availableDisplayModes: s ?? ["inline", "fullscreen"],
|
|
17
18
|
styles: { variables: n() }
|
|
18
19
|
}), [
|
|
19
20
|
i,
|
|
20
21
|
r,
|
|
21
22
|
a,
|
|
22
23
|
o,
|
|
23
|
-
t
|
|
24
|
+
t,
|
|
25
|
+
s
|
|
24
26
|
]);
|
|
25
27
|
//#endregion
|
|
26
28
|
export { r as useMcpAppHostContext };
|
|
@@ -4,12 +4,12 @@ import { useCallback as i, useEffect as a, useRef as o } from "react";
|
|
|
4
4
|
import { computeMcpAppSeedKey as s, resolveMcpAppToolResult as c } from "@epam/ai-dial-mcp-apps";
|
|
5
5
|
//#region src/mcp-apps/useOpenMcpAppCanvas/useOpenMcpAppCanvas.ts
|
|
6
6
|
var l = (l, u, d, f) => {
|
|
7
|
-
let { openCanvas: p, openCanvasLoading: m } = r(), { hostContext:
|
|
8
|
-
if (
|
|
7
|
+
let { openCanvas: p, openCanvasLoading: m, closeCanvas: h } = r(), { hostContext: g, sandboxUrl: _, fetchResourceHtml: v, callTool: y } = u, b = i((e) => e === "inline" ? (h(), "inline") : "fullscreen", [h]), x = o(null), S = i(async (r, i, a, o = !1) => {
|
|
8
|
+
if (_ == null) return !1;
|
|
9
9
|
f?.(), m(d.title, i);
|
|
10
10
|
try {
|
|
11
11
|
let e = s(a), n = async () => {
|
|
12
|
-
let [e, t] = await Promise.all([
|
|
12
|
+
let [e, t] = await Promise.all([v(r.toolsetId, r.resourceUri), c(r, a, y)]);
|
|
13
13
|
return {
|
|
14
14
|
html: e,
|
|
15
15
|
toolResult: t
|
|
@@ -21,14 +21,14 @@ var l = (l, u, d, f) => {
|
|
|
21
21
|
}, e)), p({
|
|
22
22
|
type: t.McpApp,
|
|
23
23
|
html: u,
|
|
24
|
-
sandboxUrl:
|
|
25
|
-
toolName: r.mcpToolName,
|
|
24
|
+
sandboxUrl: _,
|
|
26
25
|
toolInput: a?.toolInput,
|
|
27
26
|
toolResult: f,
|
|
28
|
-
hostContext:
|
|
29
|
-
onToolCall: (e, t) =>
|
|
27
|
+
hostContext: g,
|
|
28
|
+
onToolCall: (e, t) => y(r.toolsetId, e, t, r.kind),
|
|
29
|
+
onRequestDisplayMode: b,
|
|
30
30
|
onReload: () => {
|
|
31
|
-
i != null && l.invalidate(i),
|
|
31
|
+
i != null && l.invalidate(i), x.current?.(r, i, a, !0);
|
|
32
32
|
}
|
|
33
33
|
}, d.title, i), !0;
|
|
34
34
|
} catch (r) {
|
|
@@ -43,16 +43,17 @@ var l = (l, u, d, f) => {
|
|
|
43
43
|
p,
|
|
44
44
|
m,
|
|
45
45
|
f,
|
|
46
|
-
g,
|
|
47
|
-
h,
|
|
48
46
|
_,
|
|
47
|
+
g,
|
|
49
48
|
v,
|
|
49
|
+
y,
|
|
50
50
|
l,
|
|
51
|
-
d
|
|
51
|
+
d,
|
|
52
|
+
b
|
|
52
53
|
]);
|
|
53
54
|
return a(() => {
|
|
54
|
-
|
|
55
|
-
}, [
|
|
55
|
+
x.current = S;
|
|
56
|
+
}, [S]), { openMcpAppCanvas: S };
|
|
56
57
|
};
|
|
57
58
|
//#endregion
|
|
58
59
|
export { l as useOpenMcpAppCanvas };
|
package/mcp-apps.d.ts
CHANGED
|
@@ -36,6 +36,9 @@ toolsetId: string,
|
|
|
36
36
|
resourceUri: string,
|
|
37
37
|
) => Promise<string>;
|
|
38
38
|
|
|
39
|
+
/** Display mode an MCP App can ask the host to switch to via `ui/request-display-mode` — the MCP UI protocol's `inline`/`fullscreen`/`pip` union. */
|
|
40
|
+
declare type McpAppDisplayMode = NonNullable<McpUiHostContext['displayMode']>;
|
|
41
|
+
|
|
39
42
|
/**
|
|
40
43
|
* Dependencies the host must inject into `useMcpAppInlinePreview` /
|
|
41
44
|
* `McpAppInlinePreview` — everything that requires host context (theming,
|
|
@@ -63,6 +66,12 @@ export declare interface McpAppHostContextParams {
|
|
|
63
66
|
locale: string;
|
|
64
67
|
/** Operator-configured MCP App user-agent override. Defaults to `'ai-dial-chat'`. */
|
|
65
68
|
mcpAppUserAgent?: string;
|
|
69
|
+
/**
|
|
70
|
+
* Display modes the host can switch an app between via
|
|
71
|
+
* `ui/request-display-mode`. Defaults to `['inline', 'fullscreen']` — the
|
|
72
|
+
* compact inline preview and the full-width canvas.
|
|
73
|
+
*/
|
|
74
|
+
availableDisplayModes?: McpAppDisplayMode[];
|
|
66
75
|
}
|
|
67
76
|
|
|
68
77
|
/** Thrown by `McpAppsApiClient.fetchResourceHtml` on a non-OK response, carrying the HTTP status so callers can distinguish `403` (forbidden) from any other failure. */
|
|
@@ -181,9 +190,10 @@ export declare const useMcpAppHostAdapter: (displayMode: "inline" | "fullscreen"
|
|
|
181
190
|
* `ui/initialize` handshake, shared by every place that mounts an app —
|
|
182
191
|
* a full-width attachment canvas (`displayMode: 'fullscreen'`) and a compact
|
|
183
192
|
* inline preview under a message (`displayMode: 'inline'`) — so the app can
|
|
184
|
-
* size/style itself differently for each
|
|
193
|
+
* size/style itself differently for each, and knows (via
|
|
194
|
+
* `availableDisplayModes`) which surfaces it may ask the host to switch to.
|
|
185
195
|
*/
|
|
186
|
-
export declare const useMcpAppHostContext: (displayMode: "inline" | "fullscreen", { theme, mcpAppTheme, locale, mcpAppUserAgent }: McpAppHostContextParams) => McpUiHostContext;
|
|
196
|
+
export declare const useMcpAppHostContext: (displayMode: "inline" | "fullscreen", { theme, mcpAppTheme, locale, mcpAppUserAgent, availableDisplayModes, }: McpAppHostContextParams) => McpUiHostContext;
|
|
187
197
|
|
|
188
198
|
/**
|
|
189
199
|
* Discovers MCP Apps-capable tools available to the current conversation, merging two
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@epam/ai-dial-chat-hooks",
|
|
3
3
|
"description": "Framework-level React hooks extracted from AI DIAL Chat for building custom chat interfaces",
|
|
4
|
-
"version": "1.1.0-dev.
|
|
4
|
+
"version": "1.1.0-dev.467",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./index.js",
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"dependencies": {
|
|
99
|
-
"dompurify": "3.4.
|
|
99
|
+
"dompurify": "3.4.15",
|
|
100
100
|
"fflate": "^0.8.3",
|
|
101
101
|
"lru-cache": "^10.4.3",
|
|
102
102
|
"mime-types": "^3.0.2",
|
|
@@ -104,21 +104,21 @@
|
|
|
104
104
|
},
|
|
105
105
|
"peerDependencies": {
|
|
106
106
|
"react": "^19.2.6",
|
|
107
|
-
"@epam/ai-dial-attachment-canvas": "1.1.0-dev.
|
|
108
|
-
"@epam/ai-dial-attachment-input": "1.1.0-dev.
|
|
109
|
-
"@epam/ai-dial-
|
|
110
|
-
"@epam/ai-dial-
|
|
111
|
-
"@epam/ai-dial-chat-
|
|
112
|
-
"@epam/ai-dial-chat-
|
|
113
|
-
"@epam/ai-dial-
|
|
114
|
-
"@epam/ai-dial-mcp-apps": "1.1.0-dev.
|
|
115
|
-
"@epam/ai-dial-publish-panel": "1.1.0-dev.
|
|
116
|
-
"@epam/ai-dial-quotations": "1.1.0-dev.
|
|
107
|
+
"@epam/ai-dial-attachment-canvas": "1.1.0-dev.467",
|
|
108
|
+
"@epam/ai-dial-attachment-input": "1.1.0-dev.467",
|
|
109
|
+
"@epam/ai-dial-builder-form": "1.1.0-dev.467",
|
|
110
|
+
"@epam/ai-dial-catalog": "1.1.0-dev.467",
|
|
111
|
+
"@epam/ai-dial-chat-api-client": "1.1.0-dev.467",
|
|
112
|
+
"@epam/ai-dial-chat-overlay": "1.1.0-dev.467",
|
|
113
|
+
"@epam/ai-dial-chat-shared": "1.1.0-dev.467",
|
|
114
|
+
"@epam/ai-dial-mcp-apps": "1.1.0-dev.467",
|
|
115
|
+
"@epam/ai-dial-publish-panel": "1.1.0-dev.467",
|
|
116
|
+
"@epam/ai-dial-quotations": "1.1.0-dev.467",
|
|
117
117
|
"@epam/ai-dial-react-file-manager": "*",
|
|
118
|
-
"@epam/ai-dial-scheduled-tasks": "1.1.0-dev.
|
|
119
|
-
"@epam/ai-dial-share": "1.1.0-dev.
|
|
120
|
-
"@epam/ai-dial-skill-editor": "1.1.0-dev.
|
|
121
|
-
"@epam/ai-dial-source-panel": "1.1.0-dev.
|
|
118
|
+
"@epam/ai-dial-scheduled-tasks": "1.1.0-dev.467",
|
|
119
|
+
"@epam/ai-dial-share": "1.1.0-dev.467",
|
|
120
|
+
"@epam/ai-dial-skill-editor": "1.1.0-dev.467",
|
|
121
|
+
"@epam/ai-dial-source-panel": "1.1.0-dev.467",
|
|
122
122
|
"@epam/ai-dial-ui-kit": "*",
|
|
123
123
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
124
124
|
"@epam/pdf-highlighter-kit": ">=0.0.14",
|
|
@@ -131,6 +131,9 @@
|
|
|
131
131
|
"@epam/ai-dial-attachment-input": {
|
|
132
132
|
"optional": true
|
|
133
133
|
},
|
|
134
|
+
"@epam/ai-dial-builder-form": {
|
|
135
|
+
"optional": true
|
|
136
|
+
},
|
|
134
137
|
"@epam/ai-dial-catalog": {
|
|
135
138
|
"optional": true
|
|
136
139
|
},
|
|
@@ -143,9 +146,6 @@
|
|
|
143
146
|
"@epam/ai-dial-chat-shared": {
|
|
144
147
|
"optional": true
|
|
145
148
|
},
|
|
146
|
-
"@epam/ai-dial-deployment-creation-form": {
|
|
147
|
-
"optional": true
|
|
148
|
-
},
|
|
149
149
|
"@epam/ai-dial-mcp-apps": {
|
|
150
150
|
"optional": true
|
|
151
151
|
},
|
package/utils.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { DeploymentCreationFormLocaleEntry } from '@epam/ai-dial-
|
|
2
|
-
import { DeploymentCreationFormLocaleOption } from '@epam/ai-dial-
|
|
1
|
+
import { DeploymentCreationFormLocaleEntry } from '@epam/ai-dial-builder-form';
|
|
2
|
+
import { DeploymentCreationFormLocaleOption } from '@epam/ai-dial-builder-form';
|
|
3
3
|
import { ExportFolder } from '@epam/ai-dial-chat-shared';
|
|
4
4
|
import { LocaleTextEntryDto } from '@epam/ai-dial-chat-api-client';
|
|
5
5
|
import { Middleware } from '@epam/ai-dial-chat-api-client';
|