@epam/ai-dial-chat-hooks 1.2.0-dev.28 → 1.2.0-dev.284

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/api-error/api-error.js +7 -4
  2. package/attachment/useAttachmentValidation/useAttachmentValidation.js +26 -19
  3. package/attachments.d.ts +10 -4
  4. package/catalog/catalog-derivations.js +1 -1
  5. package/catalog/deployment-id.js +8 -2
  6. package/catalog/map-deployment-limits-to-catalog.js +16 -24
  7. package/catalog/map-deployment-limits-to-input.js +81 -9
  8. package/catalog/map-deployment-to-catalog-item.js +34 -34
  9. package/catalog/map-entity-details-to-catalog.js +7 -0
  10. package/catalog/map-skill-to-catalog-item.js +55 -48
  11. package/catalog/publish.js +6 -5
  12. package/catalog/useApplicationCredentials/useApplicationCredentials.js +39 -0
  13. package/catalog/useCatalogEditNavigation/useCatalogEditNavigation.js +122 -101
  14. package/catalog/usePublishFolders/usePublishFolders.js +1 -1
  15. package/catalog/useSkillDetailsPanelData/useSkillDetailsPanelData.js +39 -39
  16. package/catalog/useSkillItemDetails.js +17 -13
  17. package/catalog.d.ts +139 -34
  18. package/catalog.js +23 -22
  19. package/conversation/conversation-transfer/export-conversation.js +24 -16
  20. package/conversation/conversation-transfer/import-conversation.js +80 -31
  21. package/conversation/conversation-transfer/queue.js +8 -5
  22. package/conversation/create-chat-stream-api.js +85 -49
  23. package/conversation/message-utils.js +44 -2
  24. package/conversation/stage.js +27 -0
  25. package/conversation/useActiveConversationSync/useActiveConversationSync.js +7 -8
  26. package/conversation/useConversationExport/useConversationExport.js +9 -9
  27. package/conversation/useConversationHandlers/useConversationHandlers.js +73 -57
  28. package/conversation/useConversationImport/useConversationImport.js +123 -121
  29. package/conversation/useConversationPanelItems/useConversationPanelItems.js +50 -32
  30. package/conversation/useConversationScroll/useConversationScroll.js +68 -64
  31. package/conversation/useConversationStream/apply-chunk.js +1 -1
  32. package/conversation/useConversationStream/frame-scheduler.js +39 -0
  33. package/conversation/useConversationStream/generation-resume.js +122 -64
  34. package/conversation/useConversationStream/useConversationStream.js +265 -116
  35. package/conversation/useMessageSelectionReply/useMessageSelectionReply.js +189 -0
  36. package/conversation-sources/useConversationSources/useConversationSources.js +31 -24
  37. package/conversation-sources.d.ts +1 -1
  38. package/conversation-transfer.d.ts +2 -1
  39. package/conversation.d.ts +295 -17
  40. package/conversation.js +32 -29
  41. package/file-manager-canvas.d.ts +53 -5
  42. package/file-manager.d.ts +156 -26
  43. package/file-manager.js +25 -23
  44. package/files/attachment-canvas.js +74 -40
  45. package/files/attachment-types.js +14 -13
  46. package/files/dial-file-manager-mapping.util.js +2 -1
  47. package/files/dial-file-manager-path.util.js +23 -1
  48. package/files/dial-file-manager.model.js +23 -19
  49. package/files/dial-file-manager.types.js +3 -3
  50. package/files/useDialFileListing/useDialFileListing.js +139 -127
  51. package/files/useDialFileManager/useDialFileManager.js +132 -128
  52. package/files/useDialFileManagerSections/useDialFileManagerSections.js +155 -0
  53. package/files/useDialFileManagerTabConfig/useDialFileManagerTabConfig.js +20 -19
  54. package/files/useDialFileMutations/useDialFileMutations.js +33 -32
  55. package/files/useDialFileUploadBatch/useDialFileUploadBatch.js +117 -110
  56. package/files/useFileAttachmentPicker/useFileAttachmentPicker.js +49 -0
  57. package/index.d.ts +1178 -112
  58. package/index.js +136 -122
  59. package/mcp-apps/useMcpAppHostAdapter/useMcpAppHostAdapter.js +7 -5
  60. package/mcp-apps/useMcpAppHostContext/useMcpAppHostContext.js +1 -1
  61. package/mcp-apps/useMcpAppTools/useMcpAppTools.js +1 -1
  62. package/mcp-apps/useOpenMcpAppCanvas/useOpenMcpAppCanvas.js +25 -23
  63. package/mcp-apps.d.ts +8 -6
  64. package/oauth/toolset-id.js +5 -3
  65. package/oauth/useToolsetLogin/useToolsetLogin.js +8 -8
  66. package/oauth.d.ts +32 -0
  67. package/oauth.js +9 -9
  68. package/package.json +26 -21
  69. package/scheduled-task/scheduled-task-description.js +81 -0
  70. package/scheduled-task/scheduled-task-preparation.js +24 -0
  71. package/scheduled-task/scheduled-task-trigger.js +74 -71
  72. package/scheduled-task/scheduled-tasks-api-client.js +19 -0
  73. package/scheduled-task/use-scheduled-task-runs.js +194 -0
  74. package/scheduled-task/use-scheduled-tasks.js +93 -0
  75. package/scheduled-tasks.d.ts +197 -3
  76. package/scheduled-tasks.js +7 -2
  77. package/shared/application-schema.js +5 -2
  78. package/shared/cron-day-of-month.js +13 -0
  79. package/skill/skill-archive.js +19 -0
  80. package/skill/skill-types.js +8 -7
  81. package/skill/skill.js +53 -27
  82. package/skill/useSkillArchiveImport/useSkillArchiveImport.js +79 -0
  83. package/skill/useSkillEditorLoad.js +65 -59
  84. package/skill/useSkillEditorSubmit.js +108 -84
  85. package/skill/useSkillFileActions.js +70 -58
  86. package/skill-editor.d.ts +160 -8
  87. package/skill-editor.js +9 -8
  88. package/usage/map-usage-data-to-dashboard.js +66 -0
  89. package/usage/map-user-usage-to-model-limits.js +202 -0
  90. package/usage.d.ts +125 -0
  91. package/usage.js +3 -0
  92. package/usePageFileDrag/usePageFileDrag.js +3 -3
  93. package/utils.d.ts +26 -6
  94. package/utils.js +10 -10
package/skill/skill.js CHANGED
@@ -1,48 +1,74 @@
1
- import { SkillFileNodeKind as e } from "@epam/ai-dial-skill-editor";
2
- import { unzipSync as t } from "fflate";
3
- import { parse as n, stringify as r } from "yaml";
1
+ import { ENTITY_DESCRIPTION_MAX_LENGTH as e, ENTITY_INSTRUCTIONS_MAX_LENGTH as t, ENTITY_NAME_MAX_LENGTH as n, HIDDEN_FILE as r, exceedsMaxLength as i } from "@epam/ai-dial-chat-shared";
2
+ import { SkillFileNodeKind as a } from "@epam/ai-dial-skill-editor";
3
+ import { unzipSync as o } from "fflate";
4
+ import { parse as s, stringify as c } from "yaml";
4
5
  //#region src/skill/skill.ts
5
- var i = "SKILL.md", a = 1048576, o = 16777216, s = 100, c = new Set([".dial-resource", ".dial-folder"]), l = new Set(["files", "v"]), u = /^[a-zA-Z]:/, d = /[\x00-\x1f]/, f = (e) => {
6
- if (e === "" || e.startsWith("/") || u.test(e) || e.includes("\\") || d.test(e)) return !1;
6
+ var l = "SKILL.md", u = 1048576, d = 16777216, f = 100, p = r, m = `/${p}`, h = (e) => e.endsWith(m) && e.length > m.length, g = (e) => e.slice(0, -m.length), _ = new Set([
7
+ ".dial-resource",
8
+ ".dial-folder",
9
+ p
10
+ ]), v = new Set(["files", "v"]), y = /^[a-zA-Z]:/, b = /[\x00-\x1f]/, x = (e) => {
11
+ if (e === "" || e.startsWith("/") || y.test(e) || e.includes("\\") || b.test(e)) return !1;
7
12
  let t = e.split("/");
8
- return !(t.some((e) => e === "" || e === "." || e === "..") || t.some((e) => c.has(e)) || l.has(t[0]));
9
- }, p = (e) => e.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-/, "").replace(/-$/, ""), m = ({ name: e, description: t, instructions: n }) => `---\n${r({
13
+ return !(t.some((e) => e === "" || e === "." || e === "..") || t.some((e) => _.has(e)) || v.has(t[0]));
14
+ }, S = (e) => e.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-/, "").replace(/-$/, ""), C = {
15
+ name: n,
16
+ description: e,
17
+ instructions: t
18
+ }, w = (e) => {
19
+ let t = {};
20
+ for (let n of Object.keys(C)) {
21
+ let r = C[n];
22
+ i(e[n].trim(), r) && (t[n] = r);
23
+ }
24
+ return t;
25
+ }, T = ({ name: e, description: t, instructions: n }) => `---\n${c({
10
26
  name: e,
11
27
  description: t
12
- }).trimEnd()}\n---\n\n${n}`, h = (e, t, n, i) => `---\n${r({
28
+ }).trimEnd()}\n---\n\n${n}`, E = (e, t, n, r) => `---\n${c({
13
29
  ...e,
14
30
  name: t,
15
31
  description: n
16
- }).trimEnd()}\n---\n\n${i}`, g = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/, _ = (e) => {
17
- let t = g.exec(e);
32
+ }).trimEnd()}\n---\n\n${r}`, D = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/, O = /^---[ \t]*$/, k = (e) => {
33
+ let t = e.replace(/^\uFEFF/, "").replace(/\r\n/g, "\n").split("\n"), n = t.findIndex((e) => e.trim() !== "");
34
+ return n === -1 || !O.test(t[n]) ? !1 : t.some((e, t) => t > n && O.test(e));
35
+ }, A = (e) => {
36
+ let t = D.exec(e);
18
37
  if (!t) throw Error("SKILL.md is missing its YAML frontmatter block");
19
- let [, r, i] = t;
38
+ let [, n, r] = t;
20
39
  return {
21
- frontmatter: n(r) ?? {},
22
- instructions: i.replace(/^\r?\n/, "")
40
+ frontmatter: s(n) ?? {},
41
+ instructions: r.replace(/^\r?\n/, "")
23
42
  };
24
- }, v = (e) => {
25
- let n = t(e), r = n[i];
26
- if (r == null) throw Error(`Skill archive is missing a root ${i} file`);
27
- let a = /* @__PURE__ */ new Map();
28
- for (let [e, t] of Object.entries(n)) e === "SKILL.md" || e.endsWith("/") || a.set(e, t);
43
+ }, j = (e) => {
44
+ let t = o(e), n = t[l];
45
+ if (n == null) throw Error(`Skill archive is missing a root ${l} file`);
46
+ let r = /* @__PURE__ */ new Map(), i = [];
47
+ for (let [e, n] of Object.entries(t)) if (!(e === "SKILL.md" || e.endsWith("/"))) {
48
+ if (h(e)) {
49
+ i.push(g(e));
50
+ continue;
51
+ }
52
+ e !== p && r.set(e, n);
53
+ }
29
54
  return {
30
- manifestText: new TextDecoder().decode(r),
31
- files: a
55
+ manifestText: new TextDecoder().decode(n),
56
+ files: r,
57
+ folders: i
32
58
  };
33
- }, y = (e) => {
59
+ }, M = (e) => {
34
60
  let t = e.lastIndexOf("/");
35
61
  return t === -1 ? e : e.slice(t + 1);
36
- }, b = (e) => new Blob([new Uint8Array(e)]), x = (e, t, n, r) => Object.keys(e).length > 0 ? h(e, t, n, r) : m({
62
+ }, N = (e) => new Blob([new Uint8Array(e)]), P = (e, t, n, r) => Object.keys(e).length > 0 ? E(e, t, n, r) : T({
37
63
  name: t,
38
64
  description: n,
39
65
  instructions: r
40
- }), S = (t, n) => {
41
- let r = t.filter((t) => t.kind === e.File);
66
+ }), F = (e, t) => {
67
+ let n = e.filter((e) => e.kind === a.File), r = e.filter((t) => t.kind === a.Folder && !e.some((e) => e.path.startsWith(`${t.path}/`))).map((e) => `${e.path}${m}`);
42
68
  return {
43
- filePaths: r.map((e) => e.path),
44
- files: r.map((e) => b(n.get(e.path)?.bytes ?? new Uint8Array()))
69
+ filePaths: [...n.map((e) => e.path), ...r],
70
+ files: [...n.map((e) => N(t.get(e.path)?.bytes ?? new Uint8Array())), ...r.map(() => new Blob([]))]
45
71
  };
46
72
  };
47
73
  //#endregion
48
- export { a as SKILL_FILE_UPLOAD_MAX_BYTES, i as SKILL_MANIFEST_FILE, s as SKILL_UPLOAD_MAX_FILES, o as SKILL_UPLOAD_MAX_TOTAL_BYTES, S as buildSkillFilesPayload, m as buildSkillManifest, x as buildSkillManifestForSubmit, h as buildSkillManifestFromFrontmatter, f as isValidSkillRelativePath, y as nameFromPath, p as normalizeSkillName, _ as parseSkillManifest, b as skillFileBytesToBlob, v as unpackSkillArchive };
74
+ export { u as SKILL_FILE_UPLOAD_MAX_BYTES, p as SKILL_FOLDER_MARKER, l as SKILL_MANIFEST_FILE, C as SKILL_TEXT_FIELD_MAX_LENGTHS, f as SKILL_UPLOAD_MAX_FILES, d as SKILL_UPLOAD_MAX_TOTAL_BYTES, F as buildSkillFilesPayload, T as buildSkillManifest, P as buildSkillManifestForSubmit, E as buildSkillManifestFromFrontmatter, w as getSkillFieldLengthViolations, h as isSkillFolderMarkerPath, x as isValidSkillRelativePath, M as nameFromPath, S as normalizeSkillName, A as parseSkillManifest, N as skillFileBytesToBlob, g as skillFolderMarkerParent, k as startsWithFrontmatterBlock, j as unpackSkillArchive };
@@ -0,0 +1,79 @@
1
+ import { getApiErrorStatus as e } from "../../api-error/api-error.js";
2
+ import { useCallback as t, useEffect as n, useRef as r, useState as i } from "react";
3
+ //#region src/skill/useSkillArchiveImport/useSkillArchiveImport.ts
4
+ var a = "SKILL.md", o = /* @__PURE__ */ function(e) {
5
+ return e.Idle = "idle", e.Uploading = "uploading", e.Success = "success", e.Error = "error", e;
6
+ }({}), s = /* @__PURE__ */ function(e) {
7
+ return e.Validation = "validation", e.Collision = "collision", e.RateLimited = "rateLimited", e.ServiceUnavailable = "serviceUnavailable", e.Generic = "generic", e;
8
+ }({}), c = /* @__PURE__ */ function(e) {
9
+ return e.UnsupportedFilename = "unsupportedFilename", e;
10
+ }({}), l = (e) => {
11
+ switch (e) {
12
+ case 400:
13
+ case 413:
14
+ case 422: return "validation";
15
+ case 409: return "collision";
16
+ case 429: return "rateLimited";
17
+ case 502:
18
+ case 503: return "serviceUnavailable";
19
+ default: return "generic";
20
+ }
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(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);
31
+ try {
32
+ let e = await o(t, r);
33
+ if (r.aborted || (await s(e), r.aborted)) return;
34
+ h("success"), p(!1);
35
+ } catch (t) {
36
+ if (r.aborted) return;
37
+ let n = l(e(t));
38
+ h("error"), y(n), c(t, n);
39
+ } finally {
40
+ b.current === n && (b.current = null);
41
+ }
42
+ }, [
43
+ o,
44
+ s,
45
+ c
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);
50
+ }, []), w = t(() => {
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
+ ]);
66
+ return {
67
+ isDialogOpen: f,
68
+ status: m,
69
+ isUploading: m === "uploading",
70
+ selectionRejectionReason: g,
71
+ errorKind: v,
72
+ openDialog: S,
73
+ closeDialog: C,
74
+ handleFilesSelected: T,
75
+ handleFilesRejected: w
76
+ };
77
+ };
78
+ //#endregion
79
+ export { s as SkillArchiveImportErrorKind, o as SkillArchiveImportStatus, c as SkillArchiveSelectionRejectionReason, l as classifySkillArchiveImportError, d as useSkillArchiveImport };
@@ -1,103 +1,109 @@
1
1
  import { getApiErrorStatus as e } from "../api-error/api-error.js";
2
2
  import { stripSurroundingSlashes as t, stripTrailingSlashes as n } from "../shared/string-utils.js";
3
- import { SKILL_MANIFEST_FILE as r, nameFromPath as i, parseSkillManifest as a, unpackSkillArchive as o } from "./skill.js";
4
- import { useEffect as s, useRef as c, useState as l } from "react";
5
- import { SkillFileNodeKind as u } from "@epam/ai-dial-skill-editor";
3
+ import { SKILL_FOLDER_MARKER as r, SKILL_MANIFEST_FILE as i, isSkillFolderMarkerPath as a, nameFromPath as o, parseSkillManifest as s, skillFolderMarkerParent as c, unpackSkillArchive as l } from "./skill.js";
4
+ import { useEffect as u, useRef as d, useState as f } from "react";
5
+ import { SkillFileNodeKind as p } from "@epam/ai-dial-skill-editor";
6
6
  //#region src/skill/useSkillEditorLoad.ts
7
- var d = /* @__PURE__ */ function(e) {
7
+ var m = /* @__PURE__ */ function(e) {
8
8
  return e.Loading = "loading", e.Loaded = "loaded", e.Error = "error", e.Forbidden = "forbidden", e.NotFound = "not-found", e;
9
- }({}), f = class extends Error {}, p = (e, r) => {
9
+ }({}), h = class extends Error {}, g = class extends Error {}, _ = (e, r) => {
10
10
  let i = e.parentPath ? t(e.parentPath) : "", a = `${n(r)}/files`;
11
11
  return i === a ? e.name : i.startsWith(`${a}/`) ? `${i.slice(a.length + 1)}/${e.name}` : i === "files" ? e.name : i.startsWith("files/") ? `${i.slice(6)}/${e.name}` : null;
12
- }, m = async (e, t, n) => {
12
+ }, v = async (e, t, n) => {
13
13
  let r = await e.downloadSkill(t, n), i = r.headers.get("etag");
14
- if (!i) throw new f("Skill ETag is missing");
14
+ if (!i) throw new g("Skill ETag is missing");
15
15
  try {
16
- let e = await r.arrayBuffer(), { manifestText: t, files: n } = o(new Uint8Array(e));
16
+ let e = await r.arrayBuffer(), { manifestText: t, files: n, folders: a } = l(new Uint8Array(e));
17
17
  return {
18
18
  etag: i,
19
19
  manifestText: t,
20
- files: n
20
+ files: n,
21
+ folders: a
21
22
  };
22
23
  } catch {
23
- throw new f("Skill ZIP is invalid");
24
+ throw new h("Skill ZIP is invalid");
24
25
  }
25
- }, h = async (e, t, n) => {
26
- let [i, a] = await Promise.all([e.downloadSkillFile(t, n, r), e.listSkillFiles({
26
+ }, y = async (e, t, n) => {
27
+ let [s, l] = await Promise.all([e.downloadSkillFile(t, n, i), e.listSkillFiles({
27
28
  bucket: t,
28
29
  path: n,
29
30
  filePath: "",
30
31
  recursive: !0
31
- })]), o = a.items.find((e) => e.nodeType === "item" && p(e, n) === "SKILL.md"), s = i.headers.get("etag") ?? o?.etag;
32
- if (!s) throw Error("Skill ETag is missing");
33
- let c = a.items.filter((e) => e.nodeType === "item").map((e) => ({
34
- item: e,
35
- path: p(e, n)
36
- })).filter((e) => e.path != null && e.path !== "SKILL.md"), l = await Promise.all(c.map(async ({ path: r }) => {
32
+ })]), u = l.items.find((e) => e.nodeType === "item" && _(e, n) === "SKILL.md"), d = s.headers.get("etag") ?? u?.etag;
33
+ if (!d) throw new g("Skill ETag is missing");
34
+ let f = l.items.filter((e) => e.nodeType === "item").map((e) => _(e, n)).filter((e) => e != null && e !== "SKILL.md"), p = f.filter(a).map(c), m = f.filter((e) => o(e) !== r), h = await Promise.all(m.map(async (r) => {
37
35
  let i = await e.downloadSkillFile(t, n, r);
38
36
  return [r, new Uint8Array(await i.arrayBuffer())];
39
37
  }));
40
38
  return {
41
- etag: s,
42
- manifestText: await i.text(),
43
- files: new Map(l)
39
+ etag: d,
40
+ manifestText: await s.text(),
41
+ files: new Map(h),
42
+ folders: p
44
43
  };
45
- }, g = ({ isEditMode: t, bucket: n, skillPath: r, client: o }) => {
46
- let [d, p] = l(t ? "loading" : "loaded"), [g, _] = l(0), [v, y] = l(), b = c(void 0), x = c({}), S = c(void 0), [C, w] = l([]), T = c(/* @__PURE__ */ new Map());
47
- return s(() => {
44
+ }, b = ({ isEditMode: t, bucket: n, skillPath: r, client: i }) => {
45
+ let [a, c] = f(t ? "loading" : "loaded"), [l, m] = f(0), [_, b] = f(), x = d(void 0), S = d({}), C = d(void 0), [w, T] = f([]), E = d(/* @__PURE__ */ new Map());
46
+ return u(() => {
48
47
  if (!t || !n) return;
49
48
  if (r == null) {
50
- p("error");
49
+ c("error");
51
50
  return;
52
51
  }
53
- let s = !1;
54
- return p("loading"), (async () => {
55
- if (await Promise.resolve(), !s) try {
52
+ let a = !1;
53
+ return c("loading"), (async () => {
54
+ if (await Promise.resolve(), !a) try {
56
55
  let t;
57
56
  try {
58
- t = await m(o, n, r);
59
- } catch (i) {
60
- let a = e(i);
61
- if (!(i instanceof f) && a !== 400) throw i;
62
- t = await h(o, n, r);
57
+ t = await v(i, n, r);
58
+ } catch (a) {
59
+ if (a instanceof g) throw a;
60
+ let o = e(a);
61
+ if (!(a instanceof h) && o !== 400) throw a;
62
+ t = await y(i, n, r);
63
63
  }
64
- let { frontmatter: c, instructions: l } = a(t.manifestText);
65
- if (s) return;
66
- b.current = t.etag, x.current = c, S.current = r, T.current = new Map([...t.files].map(([e, t]) => [e, { bytes: t }])), w([...t.files.keys()].map((e) => ({
64
+ let { frontmatter: l, instructions: u } = s(t.manifestText);
65
+ if (a) return;
66
+ x.current = t.etag, S.current = l, C.current = r, E.current = new Map([...t.files].map(([e, t]) => [e, { bytes: t }]));
67
+ let d = [...t.files.keys()].map((e) => ({
67
68
  path: e,
68
- name: i(e),
69
- kind: u.File
70
- }))), y({
71
- name: typeof c.name == "string" ? c.name : "",
72
- description: typeof c.description == "string" ? c.description : "",
73
- instructions: l
74
- }), p("loaded");
69
+ name: o(e),
70
+ kind: p.File
71
+ })), f = t.folders.filter((e) => !t.files.has(e)).map((e) => ({
72
+ path: e,
73
+ name: o(e),
74
+ kind: p.Folder
75
+ }));
76
+ T([...d, ...f]), b({
77
+ name: typeof l.name == "string" ? l.name : "",
78
+ description: typeof l.description == "string" ? l.description : "",
79
+ instructions: u
80
+ }), c("loaded");
75
81
  } catch (t) {
76
- if (s) return;
82
+ if (a) return;
77
83
  let n = e(t);
78
- p(n === 403 ? "forbidden" : n === 404 ? "not-found" : "error");
84
+ c(n === 403 ? "forbidden" : n === 404 ? "not-found" : "error");
79
85
  }
80
86
  })(), () => {
81
- s = !0;
87
+ a = !0;
82
88
  };
83
89
  }, [
84
90
  t,
85
91
  n,
86
92
  r,
87
- g,
88
- o
93
+ l,
94
+ i
89
95
  ]), {
90
- loadState: d,
91
- loadedValues: v,
92
- setLoadedValues: y,
93
- files: C,
94
- setFiles: w,
95
- filesContentRef: T,
96
- frontmatterRef: x,
97
- etagRef: b,
98
- loadedPathRef: S,
99
- retryLoad: () => _((e) => e + 1)
96
+ loadState: a,
97
+ loadedValues: _,
98
+ setLoadedValues: b,
99
+ files: w,
100
+ setFiles: T,
101
+ filesContentRef: E,
102
+ frontmatterRef: S,
103
+ etagRef: x,
104
+ loadedPathRef: C,
105
+ retryLoad: () => m((e) => e + 1)
100
106
  };
101
107
  };
102
108
  //#endregion
103
- export { d as SkillEditorLoadState, g as useSkillEditorLoad };
109
+ export { m as SkillEditorLoadState, b as useSkillEditorLoad };
@@ -1,135 +1,159 @@
1
1
  import { getApiErrorDetails as e, getApiErrorStatus as t } from "../api-error/api-error.js";
2
- import { buildSkillFilesPayload as n, buildSkillManifestForSubmit as r, isValidSkillRelativePath as i, normalizeSkillName as a } from "./skill.js";
3
- import { useCallback as o, useRef as s, useState as c } from "react";
4
- import { NotificationVariant as l } from "@epam/ai-dial-ui-kit";
2
+ import { SKILL_TEXT_FIELD_MAX_LENGTHS as n, buildSkillFilesPayload as r, buildSkillManifestForSubmit as i, getSkillFieldLengthViolations as a, isValidSkillRelativePath as o, normalizeSkillName as s, startsWithFrontmatterBlock as c } from "./skill.js";
3
+ import { useCallback as l, useRef as u, useState as d } from "react";
4
+ import { NotificationVariant as f } from "@epam/ai-dial-ui-kit";
5
5
  //#region src/skill/useSkillEditorSubmit.ts
6
- var u = (e, t) => JSON.stringify({
6
+ var p = (e, t) => JSON.stringify({
7
7
  values: e,
8
8
  files: [...t].sort((e, t) => e.path.localeCompare(t.path))
9
- }), d = ({ bucket: d, isEditMode: f, files: p, filesContentRef: m, frontmatterRef: h, loadedPathRef: g, etagRef: _, returnUrl: v, refetchSkills: y, client: b, messages: x, onNavigate: S, onNotify: C }) => {
10
- let [w, T] = c({}), [E, D] = c(), [O, k] = c(), [A, j] = c("idle"), M = s(null), N = o(async (n) => {
9
+ }), m = ({ bucket: m, isEditMode: h, files: g, filesContentRef: _, frontmatterRef: v, loadedPathRef: y, etagRef: b, returnUrl: x, getCreateReturnUrl: S, refetchSkills: C, client: w, messages: T, onNavigate: E, onNotify: D }) => {
10
+ let [O, k] = d({}), [A, j] = d(), [M, N] = d(!1), [P, F] = d(), [I, L] = d("idle"), R = u(null), z = u(null), B = l(async (n) => {
11
11
  switch (t(n)) {
12
12
  case 409:
13
- T({ name: x.nameConflict });
13
+ k({ name: T.nameConflict });
14
14
  return;
15
15
  case 412:
16
- T({ name: x.nameConflict });
16
+ k({ name: T.nameConflict });
17
17
  return;
18
18
  case 413:
19
- D(x.archiveTooLarge);
19
+ j(T.archiveTooLarge);
20
20
  return;
21
21
  case 503:
22
- D(x.serviceUnavailable);
22
+ j(T.serviceUnavailable), N(!0);
23
23
  return;
24
24
  case 400: {
25
25
  let { message: t } = await e(n);
26
- D(t ?? x.pathInvalid);
26
+ j(t ?? T.pathInvalid);
27
27
  return;
28
28
  }
29
29
  default: {
30
30
  let { traceId: t } = await e(n);
31
- D(x.saveError), C({
32
- variant: l.Error,
33
- message: x.saveError,
31
+ j(T.saveError), D({
32
+ variant: f.Error,
33
+ message: T.saveError,
34
34
  requestId: t
35
35
  });
36
36
  }
37
37
  }
38
- }, [x, C]), P = o(async (e) => {
39
- let t = a(e.name);
40
- if (!t || !i(t)) {
41
- T({ name: x.nameInvalid });
38
+ }, [T, D]), V = l(async (e) => {
39
+ let t = s(e.name);
40
+ if (!t || !o(t)) {
41
+ k({ name: T.nameInvalid });
42
42
  return;
43
43
  }
44
- let o = u(e, p), s = M.current, c = s != null && s.fingerprint === o, f = t, g, _, w;
45
- c ? {skillManifest: g, filePaths: _, files: w} = s : (g = r(h.current, t, e.description, e.instructions), {filePaths: _, files: w} = n(p, m.current)), j("submitting"), M.current = {
46
- fingerprint: o,
47
- bucket: d,
48
- path: f,
49
- skillManifest: g,
50
- filePaths: _,
51
- files: w
44
+ let n = p(e, g), a = R.current, c = a != null && a.fingerprint === n, l = t, u, d, h;
45
+ c ? {skillManifest: u, filePaths: d, files: h} = a : (u = i(v.current, t, e.description, e.instructions), {filePaths: d, files: h} = r(g, _.current)), L("submitting"), R.current = {
46
+ fingerprint: n,
47
+ bucket: m,
48
+ path: l,
49
+ skillManifest: u,
50
+ filePaths: d,
51
+ files: h
52
52
  };
53
53
  try {
54
- await b.createSkill(d, f, g, _, w), await y(), j("success"), C({
55
- variant: l.Success,
56
- title: x.saveSuccessTitle,
57
- message: x.createSuccess(t)
58
- }), S(v);
54
+ await w.createSkill(m, l, u, d, h), await C(), L("success"), D({
55
+ variant: f.Success,
56
+ title: T.saveSuccessTitle,
57
+ message: T.createSuccess(t)
58
+ }), E(S?.(l) ?? x);
59
59
  } catch (e) {
60
- j("failure"), await N(e);
60
+ L("failure"), await B(e);
61
61
  }
62
62
  }, [
63
- d,
64
- p,
65
63
  m,
66
- h,
64
+ g,
65
+ _,
66
+ v,
67
+ T,
68
+ w,
69
+ D,
70
+ E,
67
71
  x,
68
- b,
69
- C,
70
72
  S,
71
- v,
72
- y,
73
- N
74
- ]), F = o(async (e) => {
75
- let i = g.current, a = _.current;
76
- if (!i || !a) {
77
- D(x.saveError);
73
+ C,
74
+ B
75
+ ]), H = l(async (e) => {
76
+ let n = y.current, a = b.current;
77
+ if (!n || !a) {
78
+ j(T.saveError);
78
79
  return;
79
80
  }
80
- let o = r(h.current, e.name, e.description, e.instructions), { filePaths: s, files: c } = n(p, m.current);
81
- j("submitting");
81
+ let o = i(v.current, e.name, e.description, e.instructions), { filePaths: s, files: c } = r(g, _.current);
82
+ L("submitting");
82
83
  try {
83
- _.current = (await b.updateSkill(d, i, o, s, c, a)).etag ?? a, await y(), j("success"), C({
84
- variant: l.Success,
85
- title: x.updateSuccessTitle,
86
- message: x.updateSuccess(e.name)
87
- }), S(v);
84
+ b.current = (await w.updateSkill(m, n, o, s, c, a)).etag ?? a, await C(), L("success"), D({
85
+ variant: f.Success,
86
+ title: T.updateSuccessTitle,
87
+ message: T.updateSuccess(e.name)
88
+ }), E(x);
88
89
  } catch (e) {
89
- if (j("failure"), t(e) === 412) {
90
- k({ message: x.conflictMessage });
90
+ if (L("failure"), t(e) === 412) {
91
+ F({ message: T.conflictMessage });
91
92
  return;
92
93
  }
93
- await N(e);
94
+ await B(e);
94
95
  }
95
96
  }, [
96
- d,
97
- p,
98
97
  m,
99
- h,
100
98
  g,
101
99
  _,
102
- x,
103
- b,
104
- C,
105
- S,
106
100
  v,
107
101
  y,
108
- N
102
+ b,
103
+ T,
104
+ w,
105
+ D,
106
+ E,
107
+ x,
108
+ C,
109
+ B
110
+ ]), U = l((e) => {
111
+ let t = c(e.instructions), r = a(e);
112
+ k((e) => {
113
+ let i = { ...e };
114
+ for (let e of Object.keys(n)) {
115
+ let t = T.tooLong(n[e]);
116
+ r[e] ? i[e] = t : i[e] === t && delete i[e];
117
+ }
118
+ if (!r.instructions) {
119
+ let e = i.instructions === T.instructionsFrontmatter;
120
+ t && !e ? i.instructions = T.instructionsFrontmatter : !t && e && delete i.instructions;
121
+ }
122
+ return Object.keys(i).length === Object.keys(e).length && Object.keys(i).every((t) => i[t] === e[t]) ? e : i;
123
+ });
124
+ }, [T]), W = l(async (e) => {
125
+ if (I === "submitting" || !m) return;
126
+ let t = {};
127
+ e.name.trim() || (t.name = T.required), e.description.trim() || (t.description = T.required), e.instructions.trim() ? c(e.instructions) && (t.instructions = T.instructionsFrontmatter) : t.instructions = T.required;
128
+ let r = a(e);
129
+ for (let e of Object.keys(r)) t[e] ??= T.tooLong(n[e]);
130
+ if (Object.keys(t).length > 0) {
131
+ k(t);
132
+ return;
133
+ }
134
+ k({}), j(void 0), N(!1), F(void 0), z.current = e, h ? await H(e) : await V(e);
135
+ }, [
136
+ I,
137
+ m,
138
+ T,
139
+ h,
140
+ H,
141
+ V
109
142
  ]);
110
143
  return {
111
- phase: A,
112
- errors: w,
113
- submitError: E,
114
- conflict: O,
115
- clearConflict: () => k(void 0),
116
- handleSubmit: o(async (e) => {
117
- if (A === "submitting" || !d) return;
118
- let t = {};
119
- if (e.name.trim() || (t.name = x.required), e.description.trim() || (t.description = x.required), e.instructions.trim() || (t.instructions = x.required), Object.keys(t).length > 0) {
120
- T(t);
121
- return;
122
- }
123
- T({}), D(void 0), k(void 0), f ? await F(e) : await P(e);
124
- }, [
125
- A,
126
- d,
127
- x,
128
- f,
129
- F,
130
- P
131
- ])
144
+ phase: I,
145
+ errors: O,
146
+ submitError: A,
147
+ isSubmitErrorRetryable: M,
148
+ retrySubmit: l(() => {
149
+ let e = z.current;
150
+ e != null && W(e);
151
+ }, [W]),
152
+ conflict: P,
153
+ clearConflict: () => F(void 0),
154
+ handleSubmit: W,
155
+ handleValuesChange: U
132
156
  };
133
157
  };
134
158
  //#endregion
135
- export { d as useSkillEditorSubmit };
159
+ export { m as useSkillEditorSubmit };