@epam/ai-dial-chat-hooks 1.2.0-dev.201 → 1.2.0-dev.208

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.
@@ -44,7 +44,10 @@ var p = ({ conversation: p, conversationId: m, bucket: h, isStreaming: g, startS
44
44
  if (g || !m || !p || e === -1 || p.messages[e]?.role !== c.Assistant) return;
45
45
  let t = p.messages[e - 1];
46
46
  if (!t || t.role !== c.User) return;
47
- let n = C(), r = {
47
+ let n = C(), i = r(E) ? {
48
+ ...t.custom_content,
49
+ configuration_value: E
50
+ } : t.custom_content, a = {
48
51
  ...p.messages[e],
49
52
  content: "",
50
53
  custom_content: void 0,
@@ -52,11 +55,18 @@ var p = ({ conversation: p, conversationId: m, bucket: h, isStreaming: g, startS
52
55
  stoppedWithoutContent: void 0,
53
56
  streamErrorMessage: void 0,
54
57
  deploymentId: n
55
- }, i = {
58
+ }, o = {
56
59
  ...p,
57
- messages: [...p.messages.slice(0, e), r]
60
+ messages: [
61
+ ...p.messages.slice(0, e - 1),
62
+ {
63
+ ...t,
64
+ custom_content: i
65
+ },
66
+ a
67
+ ]
58
68
  };
59
- y.current = i, v(i), A((t) => new Set([...t].filter((t) => t < e))), _(m, t.content, e, n, t.custom_content, l(), f.Regenerate);
69
+ y.current = o, v(o), A((t) => new Set([...t].filter((t) => t < e))), _(m, t.content, e, n, i, l(), f.Regenerate);
60
70
  }, [
61
71
  p,
62
72
  m,
@@ -64,7 +74,8 @@ var p = ({ conversation: p, conversationId: m, bucket: h, isStreaming: g, startS
64
74
  g,
65
75
  C,
66
76
  v,
67
- _
77
+ _,
78
+ E
68
79
  ]), I = u((e) => {
69
80
  g || O(e);
70
81
  }, [g]), L = u(() => {
package/index.d.ts CHANGED
@@ -6190,7 +6190,7 @@ export declare interface UseShareRecipientsCountResult {
6190
6190
 
6191
6191
  /**
6192
6192
  * Headless controller for the skill-archive upload flow: dialog visibility, the exact-filename
6193
- * precheck, in-flight exclusion, and import completion. The host supplies the configured request
6193
+ * precheck, in-flight exclusion, abort-on-close, and import completion. The host supplies the configured request
6194
6194
  * and observes completion/failure through the injected callbacks; the hook never imports app
6195
6195
  * contexts, i18n, or a configured API client.
6196
6196
  */
@@ -6198,8 +6198,8 @@ export declare const useSkillArchiveImport: <TResult>({ importArchive, onImporte
6198
6198
 
6199
6199
  /** Options accepted by {@link useSkillArchiveImport}. */
6200
6200
  export declare interface UseSkillArchiveImportOptions<TResult> {
6201
- /** Submits the selected archive; the host owns request configuration and the client. */
6202
- importArchive: (file: File) => Promise<TResult>;
6201
+ /** Submits the selected archive; the host owns the client. `signal` aborts when the dialog closes or the hook unmounts mid-upload. */
6202
+ importArchive: (file: File, signal: AbortSignal) => Promise<TResult>;
6203
6203
  /** Called once after a successful import (and any awaited host follow-up) settles. */
6204
6204
  onImported: (result: TResult) => void | Promise<void>;
6205
6205
  /** Called once when the import request, or the host's follow-up in {@link onImported}, fails. */
@@ -6214,13 +6214,15 @@ export declare interface UseSkillArchiveImportResult {
6214
6214
  isDialogOpen: boolean;
6215
6215
  /** Current phase of the import. */
6216
6216
  status: SkillArchiveImportStatus;
6217
+ /** Whether an import request is in flight; the dialog stays open until it succeeds. */
6218
+ isUploading: boolean;
6217
6219
  /** Reason the current/last selection was rejected locally; `undefined` once cleared. */
6218
6220
  selectionRejectionReason: SkillArchiveSelectionRejectionReason | undefined;
6219
6221
  /** Classified failure of the last import request; `undefined` outside a request failure. */
6220
6222
  errorKind: SkillArchiveImportErrorKind | undefined;
6221
- /** Opens the dialog, unless an import is already in flight. */
6223
+ /** Opens the dialog and clears any previous rejection or request failure. */
6222
6224
  openDialog: () => void;
6223
- /** Closes the dialog and clears any rejection reason. */
6225
+ /** Closes the dialog, aborting an in-flight import, and clears any rejection reason. */
6224
6226
  closeDialog: () => void;
6225
6227
  /** Wire to the dialog drop zone's `onChange`. */
6226
6228
  handleFilesSelected: (files: File[]) => void;
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.2.0-dev.201",
4
+ "version": "1.2.0-dev.208",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
7
7
  "main": "./index.js",
@@ -111,7 +111,7 @@
111
111
  }
112
112
  },
113
113
  "dependencies": {
114
- "@epam/ai-dial-chat-api-client": "1.2.0-dev.201",
114
+ "@epam/ai-dial-chat-api-client": "1.2.0-dev.208",
115
115
  "dompurify": "3.4.15",
116
116
  "fflate": "^0.8.3",
117
117
  "lru-cache": "^10.4.3",
@@ -120,21 +120,21 @@
120
120
  },
121
121
  "peerDependencies": {
122
122
  "react": "^19.2.8",
123
- "@epam/ai-dial-attachment-canvas": "1.2.0-dev.201",
124
- "@epam/ai-dial-attachment-input": "1.2.0-dev.201",
125
- "@epam/ai-dial-catalog": "1.2.0-dev.201",
126
- "@epam/ai-dial-chat-overlay": "1.2.0-dev.201",
127
- "@epam/ai-dial-chat-shared": "1.2.0-dev.201",
128
- "@epam/ai-dial-mcp-apps": "1.2.0-dev.201",
129
- "@epam/ai-dial-publish-panel": "1.2.0-dev.201",
130
- "@epam/ai-dial-quotations": "1.2.0-dev.201",
123
+ "@epam/ai-dial-attachment-canvas": "1.2.0-dev.208",
124
+ "@epam/ai-dial-attachment-input": "1.2.0-dev.208",
125
+ "@epam/ai-dial-catalog": "1.2.0-dev.208",
126
+ "@epam/ai-dial-chat-overlay": "1.2.0-dev.208",
127
+ "@epam/ai-dial-chat-shared": "1.2.0-dev.208",
128
+ "@epam/ai-dial-mcp-apps": "1.2.0-dev.208",
129
+ "@epam/ai-dial-publish-panel": "1.2.0-dev.208",
130
+ "@epam/ai-dial-quotations": "1.2.0-dev.208",
131
131
  "@epam/ai-dial-react-file-manager": "^0.3.0-dev.16",
132
- "@epam/ai-dial-scheduled-tasks": "1.2.0-dev.201",
133
- "@epam/ai-dial-share": "1.2.0-dev.201",
134
- "@epam/ai-dial-skill-editor": "1.2.0-dev.201",
135
- "@epam/ai-dial-source-panel": "1.2.0-dev.201",
132
+ "@epam/ai-dial-scheduled-tasks": "1.2.0-dev.208",
133
+ "@epam/ai-dial-share": "1.2.0-dev.208",
134
+ "@epam/ai-dial-skill-editor": "1.2.0-dev.208",
135
+ "@epam/ai-dial-source-panel": "1.2.0-dev.208",
136
136
  "@epam/ai-dial-ui-kit": "^0.15.0-dev.23",
137
- "@epam/ai-dial-usage-dashboard": "1.2.0-dev.201",
137
+ "@epam/ai-dial-usage-dashboard": "1.2.0-dev.208",
138
138
  "@modelcontextprotocol/sdk": "^1.29.0",
139
139
  "@epam/pdf-highlighter-kit": "^0.0.19",
140
140
  "@mcp-ui/client": "^7.1.1"
@@ -19,56 +19,60 @@ var a = "SKILL.md", o = /* @__PURE__ */ function(e) {
19
19
  default: return "generic";
20
20
  }
21
21
  }, u = (e, t) => e.toLowerCase().endsWith(".md") && e !== t, d = ({ importArchive: o, onImported: s, onError: c, manifestFileName: d = a }) => {
22
- let [f, p] = i(!1), [m, h] = i("idle"), [g, _] = i(void 0), [v, y] = i(void 0), b = r(!1), x = r(!0);
23
- n(() => (x.current = !0, () => {
24
- x.current = !1;
25
- }), []);
26
- let S = t(async (t) => {
27
- b.current = !0, h("uploading"), y(void 0);
22
+ let [f, p] = i(!1), [m, h] = i("idle"), [g, _] = i(void 0), [v, y] = i(void 0), b = r(null);
23
+ n(() => () => {
24
+ b.current?.abort(), b.current = null;
25
+ }, []);
26
+ let x = t(async (t) => {
27
+ let n = new AbortController();
28
+ b.current = n;
29
+ let { signal: r } = n;
30
+ h("uploading"), y(void 0);
28
31
  try {
29
- let e = await o(t);
30
- if (!x.current || (await s(e), !x.current)) return;
31
- h("success");
32
+ let e = await o(t, r);
33
+ if (r.aborted || (await s(e), r.aborted)) return;
34
+ h("success"), p(!1);
32
35
  } catch (t) {
33
- if (!x.current) return;
36
+ if (r.aborted) return;
34
37
  let n = l(e(t));
35
38
  h("error"), y(n), c(t, n);
36
39
  } finally {
37
- b.current = !1;
40
+ b.current === n && (b.current = null);
38
41
  }
39
42
  }, [
40
43
  o,
41
44
  s,
42
45
  c
43
- ]), C = t(() => {
44
- b.current || (_(void 0), p(!0));
46
+ ]), S = t(() => {
47
+ b.current || (_(void 0), y(void 0), h("idle"), p(!0));
48
+ }, []), C = t(() => {
49
+ b.current && (b.current.abort(), b.current = null, h("idle")), p(!1), _(void 0);
45
50
  }, []), w = t(() => {
46
- p(!1), _(void 0);
47
- }, []), T = t(() => {
48
- h("error"), _("unsupportedFilename");
49
- }, []);
51
+ b.current || (h("error"), y(void 0), _("unsupportedFilename"));
52
+ }, []), T = t((e) => {
53
+ let t = e[0];
54
+ if (!(!t || b.current)) {
55
+ if (u(t.name, d)) {
56
+ w();
57
+ return;
58
+ }
59
+ _(void 0), x(t);
60
+ }
61
+ }, [
62
+ d,
63
+ w,
64
+ x
65
+ ]);
50
66
  return {
51
67
  isDialogOpen: f,
52
68
  status: m,
69
+ isUploading: m === "uploading",
53
70
  selectionRejectionReason: g,
54
71
  errorKind: v,
55
- openDialog: C,
56
- closeDialog: w,
57
- handleFilesSelected: t((e) => {
58
- let t = e[0];
59
- if (!(!t || b.current)) {
60
- if (u(t.name, d)) {
61
- T();
62
- return;
63
- }
64
- _(void 0), p(!1), S(t);
65
- }
66
- }, [
67
- d,
68
- T,
69
- S
70
- ]),
71
- handleFilesRejected: T
72
+ openDialog: S,
73
+ closeDialog: C,
74
+ handleFilesSelected: T,
75
+ handleFilesRejected: w
72
76
  };
73
77
  };
74
78
  //#endregion
package/skill-editor.d.ts CHANGED
@@ -417,7 +417,7 @@ export declare const unpackSkillArchive: (bytes: Uint8Array) => UnpackedSkillArc
417
417
 
418
418
  /**
419
419
  * Headless controller for the skill-archive upload flow: dialog visibility, the exact-filename
420
- * precheck, in-flight exclusion, and import completion. The host supplies the configured request
420
+ * precheck, in-flight exclusion, abort-on-close, and import completion. The host supplies the configured request
421
421
  * and observes completion/failure through the injected callbacks; the hook never imports app
422
422
  * contexts, i18n, or a configured API client.
423
423
  */
@@ -425,8 +425,8 @@ export declare const useSkillArchiveImport: <TResult>({ importArchive, onImporte
425
425
 
426
426
  /** Options accepted by {@link useSkillArchiveImport}. */
427
427
  export declare interface UseSkillArchiveImportOptions<TResult> {
428
- /** Submits the selected archive; the host owns request configuration and the client. */
429
- importArchive: (file: File) => Promise<TResult>;
428
+ /** Submits the selected archive; the host owns the client. `signal` aborts when the dialog closes or the hook unmounts mid-upload. */
429
+ importArchive: (file: File, signal: AbortSignal) => Promise<TResult>;
430
430
  /** Called once after a successful import (and any awaited host follow-up) settles. */
431
431
  onImported: (result: TResult) => void | Promise<void>;
432
432
  /** Called once when the import request, or the host's follow-up in {@link onImported}, fails. */
@@ -441,13 +441,15 @@ export declare interface UseSkillArchiveImportResult {
441
441
  isDialogOpen: boolean;
442
442
  /** Current phase of the import. */
443
443
  status: SkillArchiveImportStatus;
444
+ /** Whether an import request is in flight; the dialog stays open until it succeeds. */
445
+ isUploading: boolean;
444
446
  /** Reason the current/last selection was rejected locally; `undefined` once cleared. */
445
447
  selectionRejectionReason: SkillArchiveSelectionRejectionReason | undefined;
446
448
  /** Classified failure of the last import request; `undefined` outside a request failure. */
447
449
  errorKind: SkillArchiveImportErrorKind | undefined;
448
- /** Opens the dialog, unless an import is already in flight. */
450
+ /** Opens the dialog and clears any previous rejection or request failure. */
449
451
  openDialog: () => void;
450
- /** Closes the dialog and clears any rejection reason. */
452
+ /** Closes the dialog, aborting an in-flight import, and clears any rejection reason. */
451
453
  closeDialog: () => void;
452
454
  /** Wire to the dialog drop zone's `onChange`. */
453
455
  handleFilesSelected: (files: File[]) => void;