@epam/ai-dial-chat-hooks 1.1.0-dev.423 → 1.1.0-dev.430

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 (178) hide show
  1. package/{api-error-DuLNy43N.js → api-error/api-error.js} +1 -1
  2. package/api-transport/create-csrf-middleware.js +21 -0
  3. package/api-transport/create-unauthorized-middleware.js +41 -0
  4. package/attachment/useAttachmentAction/useAttachmentAction.js +74 -0
  5. package/attachment/useAttachmentValidation/useAttachmentValidation.js +35 -0
  6. package/attachments.js +3 -2
  7. package/catalog/catalog-derivations.js +10 -0
  8. package/catalog/catalog-primary-action.js +21 -0
  9. package/catalog/create-publish-api.js +27 -0
  10. package/catalog/deployment-endpoint-url.js +34 -0
  11. package/{deployment-id-CxWgJTs9.js → catalog/deployment-id.js} +1 -1
  12. package/catalog/entity-details.js +6 -0
  13. package/catalog/map-deployment-limits-to-catalog.js +73 -0
  14. package/catalog/map-deployment-limits-to-input.js +14 -0
  15. package/catalog/map-deployment-to-catalog-item.js +92 -0
  16. package/catalog/map-entity-details-to-catalog.js +350 -0
  17. package/catalog/map-prompt-to-catalog-item.js +49 -0
  18. package/catalog/map-skill-to-catalog-item.js +123 -0
  19. package/catalog/mcp-endpoint-url.js +26 -0
  20. package/catalog/publish.js +18 -0
  21. package/catalog/useCatalogEditNavigation/useCatalogEditNavigation.js +109 -0
  22. package/catalog/useCatalogItemDetails.js +101 -0
  23. package/catalog/useCatalogToolsetCredentials/useCatalogToolsetCredentials.js +146 -0
  24. package/catalog/useFavoriteEntitiesState/useFavoriteEntitiesState.js +50 -0
  25. package/catalog/usePublishFolders/usePublishFolders.js +72 -0
  26. package/catalog.js +22 -3
  27. package/conversation/announcement-message.js +42 -0
  28. package/conversation/conversation-transfer/async.js +18 -0
  29. package/conversation/conversation-transfer/attachment-refs.js +11 -0
  30. package/conversation/conversation-transfer/build-upload-path.js +27 -0
  31. package/{date-BeuD8G79.js → conversation/conversation-transfer/date.js} +1 -1
  32. package/conversation/conversation-transfer/dial-file-resolve.js +18 -0
  33. package/conversation/conversation-transfer/export-conversation.js +32 -0
  34. package/conversation/conversation-transfer/import-conversation.js +93 -0
  35. package/conversation/conversation-transfer/progress.js +39 -0
  36. package/conversation/conversation-transfer/queue.js +84 -0
  37. package/conversation/conversation-transfer/types.js +9 -0
  38. package/conversation/conversation-transfer/zip-export.js +19 -0
  39. package/conversation/conversation-transfer/zip-import.js +29 -0
  40. package/conversation/create-chat-stream-api.js +96 -0
  41. package/conversation/deriveConversationRowActionState/deriveConversationRowActionState.js +14 -0
  42. package/conversation/display-name-watch.js +5 -0
  43. package/conversation/footer-message.js +23 -0
  44. package/conversation/get-model-id-from-conversation-id.js +14 -0
  45. package/conversation/greeting.js +7 -0
  46. package/conversation/message-factory.js +19 -0
  47. package/conversation/message-utils.js +13 -0
  48. package/conversation/overlay-messages.js +8 -0
  49. package/conversation/quick-app-conversation-starters.js +29 -0
  50. package/conversation/starter-option.js +27 -0
  51. package/conversation/useActiveConversationSync/useActiveConversationSync.js +19 -0
  52. package/conversation/useAsyncConfirmDialog/useAsyncConfirmDialog.js +39 -0
  53. package/conversation/useAttachmentUpload/useAttachmentUpload.js +33 -0
  54. package/conversation/useConversationExport/useConversationExport.js +285 -0
  55. package/conversation/useConversationHandlers/attachment-to-dto.js +13 -0
  56. package/conversation/useConversationHandlers/message-factory.js +21 -0
  57. package/conversation/useConversationHandlers/message-utils.js +8 -0
  58. package/conversation/useConversationHandlers/starter-option.js +11 -0
  59. package/conversation/useConversationHandlers/useConversationHandlers.js +263 -0
  60. package/conversation/useConversationImport/useConversationImport.js +239 -0
  61. package/conversation/useConversationLookupMaps/useConversationLookupMaps.js +11 -0
  62. package/conversation/useConversationPanelItems/useConversationPanelItems.js +35 -0
  63. package/{useConversationScroll-CliIMnjP.js → conversation/useConversationScroll/useConversationScroll.js} +1 -1
  64. package/conversation/useConversationStream/apply-chunk.js +78 -0
  65. package/conversation/useConversationStream/buffered-generation.js +18 -0
  66. package/conversation/useConversationStream/conversation-path.js +8 -0
  67. package/conversation/useConversationStream/generation-resume.js +126 -0
  68. package/conversation/useConversationStream/useConversationStream.js +148 -0
  69. package/conversation/useImportFilePicker/useImportFilePicker.js +20 -0
  70. package/conversation/useTranscribeAudio/audio-transcription-error.js +12 -0
  71. package/conversation/useTranscribeAudio/transcription-retry.js +38 -0
  72. package/conversation/useTranscribeAudio/useTranscribeAudio.js +41 -0
  73. package/{useConversationSources-DKaKvjXZ.js → conversation-sources/useConversationSources/useConversationSources.js} +1 -1
  74. package/conversation-sources.js +1 -1
  75. package/conversation-transfer.js +7 -3
  76. package/conversation.d.ts +66 -0
  77. package/conversation.js +31 -2
  78. package/file-manager.d.ts +3 -4
  79. package/file-manager.js +28 -3
  80. package/files/annotation.js +15 -0
  81. package/files/attachment-canvas.js +218 -0
  82. package/files/attachment-dto-to-display.js +15 -0
  83. package/files/attachment-types.js +16 -0
  84. package/files/create-files-api.js +40 -0
  85. package/files/create-upload-file-with-progress.js +42 -0
  86. package/files/dial-file-manager-copy-move.util.js +55 -0
  87. package/files/dial-file-manager-mapping.util.js +140 -0
  88. package/files/dial-file-manager-path.util.js +72 -0
  89. package/files/dial-file-manager.model.js +25 -0
  90. package/files/dial-file-manager.types.js +10 -0
  91. package/files/dial-file-to-attachment.js +37 -0
  92. package/files/dial-file.js +30 -0
  93. package/files/dial-files-api.js +6 -0
  94. package/files/download-destination.js +6 -0
  95. package/files/file-manager-variant.js +11 -0
  96. package/files/file-name.js +19 -0
  97. package/files/prepare-download-destination.js +24 -0
  98. package/files/resolve-dial-file-api-path.js +33 -0
  99. package/files/source-content.js +37 -0
  100. package/files/useDialFileListing/useDialFileListing.js +295 -0
  101. package/files/useDialFileManager/useDialFileManager.js +146 -0
  102. package/files/useDialFileManagerTabConfig/useDialFileManagerTabConfig.js +23 -0
  103. package/files/useDialFileMetadata/useDialFileMetadata.js +42 -0
  104. package/files/useDialFileMutations/useDialFileMutations.js +359 -0
  105. package/files/useDialFileSharing/useDialFileSharing.js +70 -0
  106. package/files/useDialFileUploadBatch/useDialFileUploadBatch.js +156 -0
  107. package/index.d.ts +69 -4
  108. package/index.js +134 -28
  109. package/mcp-apps/mcp-apps-api-client.js +48 -0
  110. package/mcp-apps/useMcpAppHostAdapter/useMcpAppHostAdapter.js +26 -0
  111. package/mcp-apps/useMcpAppHostContext/useMcpAppHostContext.js +26 -0
  112. package/mcp-apps/useMcpAppTools/useMcpAppTools.js +71 -0
  113. package/mcp-apps/useOpenMcpAppCanvas/useOpenMcpAppCanvas.js +58 -0
  114. package/mcp-apps.js +6 -2
  115. package/oauth/authorize-url.js +12 -0
  116. package/oauth/handshake.js +65 -0
  117. package/oauth/popup.js +29 -0
  118. package/oauth/toolset-id.js +10 -0
  119. package/oauth/types.js +24 -0
  120. package/oauth/useOAuthCallbackCompletion/useOAuthCallbackCompletion.js +94 -0
  121. package/oauth/useToolsetLogin/useToolsetLogin.js +73 -0
  122. package/oauth.js +9 -3
  123. package/package.json +35 -23
  124. package/prompt/export-prompt.js +28 -0
  125. package/prompt/prompt-resource.js +15 -0
  126. package/prompt/prompt.js +12 -0
  127. package/prompt/usePromptsState/usePromptsState.js +42 -0
  128. package/scheduled-task/scheduled-task-mapping.js +6 -0
  129. package/{scheduled-task-trigger-D9RZCk52.js → scheduled-task/scheduled-task-trigger.js} +39 -40
  130. package/scheduled-tasks.js +3 -2
  131. package/scroll-anchoring.js +1 -1
  132. package/shared/application-schema.js +4 -0
  133. package/shared/browser-timezone.js +10 -0
  134. package/{cron-weekday-B4w29eAC.js → shared/cron-weekday.js} +1 -1
  135. package/shared/custom-apps.js +30 -0
  136. package/shared/external-services.js +18 -0
  137. package/{formatting-CZyyxBG3.js → shared/formatting.js} +1 -1
  138. package/{prompt-resource-Bt1I-8ri.js → shared/locale.js} +2 -13
  139. package/{string-utils-iBi2Y55C.js → shared/string-utils.js} +1 -1
  140. package/shared/toolset-login-events.js +13 -0
  141. package/sharing.js +3 -3
  142. package/skill/skill-file-batch-validation.js +48 -0
  143. package/skill/skill-file-preview.js +15 -0
  144. package/skill/skill-manifest.js +70 -0
  145. package/skill/skill-types.js +15 -0
  146. package/skill/skill.js +48 -0
  147. package/skill/useSkillEditorLoad.js +103 -0
  148. package/skill/useSkillEditorSubmit.js +135 -0
  149. package/skill/useSkillFileActions.js +99 -0
  150. package/skill/useSkillFilePreview.js +29 -0
  151. package/{useSkillsState-BoLlwmzb.js → skill/useSkillsState/useSkillsState.js} +1 -1
  152. package/skill-editor.js +8 -3
  153. package/skills-state.js +1 -1
  154. package/source-content.d.ts +29 -0
  155. package/source-content.js +2 -0
  156. package/usage/useUsageData/useUsageData.js +32 -0
  157. package/useChatSettingsFormConfig/useChatSettingsFormConfig.js +74 -0
  158. package/{usePanelMaxWidth-BEZYuqF9.js → usePageFileDrag/usePageFileDrag.js} +1 -11
  159. package/usePanelMaxWidth/usePanelMaxWidth.js +8 -0
  160. package/{useShareLink-xkiaxATt.js → useShareLink/useShareLink.js} +1 -1
  161. package/{useShareRecipientsCount-BgwCLKY0.js → useShareRecipientsCount/useShareRecipientsCount.js} +1 -1
  162. package/useToolsMenu/useToolsMenu.js +50 -0
  163. package/useViewportWidth/useViewportWidth.js +12 -0
  164. package/utils.js +17 -7
  165. package/viewport-layout.js +4 -2
  166. package/attachment-types-AAoN9E95.js +0 -7760
  167. package/browser-Btsa0Lmr.js +0 -607
  168. package/skill-manifest-CeG6-WSK.js +0 -4056
  169. package/useAttachmentValidation-CkMTd5lA.js +0 -102
  170. package/useConversationImport-CDRs7JF1.js +0 -826
  171. package/useDialFileManagerTabConfig-CjI46lMo.js +0 -2291
  172. package/useOAuthCallbackCompletion-CvyTKLER.js +0 -93
  173. package/useOpenMcpAppCanvas-C7-AMseH.js +0 -207
  174. package/useSkillFileActions-B-VaGD20.js +0 -373
  175. package/useSkillFilePreview-B5o1n_0F.js +0 -1244
  176. package/useToolsMenu-zURpMEn1.js +0 -1882
  177. package/useToolsetLogin-B05m134e.js +0 -195
  178. package/useUsageData-D7BxloKZ.js +0 -201
@@ -25,17 +25,6 @@ var e = (e) => e.split("-")[0].toLowerCase(), t = (t, n, r) => {
25
25
  }, a = (e, t) => e.filter((e) => e !== t).map((e) => ({
26
26
  code: e,
27
27
  label: e.toUpperCase()
28
- })), o = /* @__PURE__ */ function(e) {
29
- return e.Personal = "personal", e.SharedWithMe = "sharedWithMe", e.Public = "public", e;
30
- }({}), s = "prompts/", c = (e) => {
31
- if (!e.startsWith(s)) return null;
32
- let t = e.slice(8), n = t.indexOf("/");
33
- if (n <= 0) return null;
34
- let r = t.slice(0, n), i = t.slice(n + 1);
35
- return r === "" || i === "" ? null : {
36
- bucket: r,
37
- path: i
38
- };
39
- };
28
+ }));
40
29
  //#endregion
41
- export { r as a, e as c, a as i, c as n, i as o, n as r, t as s, o as t };
30
+ export { n as appendLocaleCode, a as buildAdditionalLocaleOptions, r as composeLocalePayload, i as decomposeLocalizedFields, t as resolveLocalizedText, e as toBaseLocale };
@@ -7,4 +7,4 @@ var e = (e, t) => e.toLowerCase().includes(t.toLowerCase()), t = (e) => {
7
7
  }
8
8
  }, n = t, r = (e) => e.replace(/^\/+|\/+$/g, "");
9
9
  //#endregion
10
- export { r as i, t as n, n as r, e as t };
10
+ export { e as includesIgnoreCase, t as safeDecodeURI, n as safeDecodeURIComponent, r as stripSurroundingSlashes };
@@ -0,0 +1,13 @@
1
+ //#region src/shared/toolset-login-events.ts
2
+ var e = "toolset-login-success", t = new EventTarget(), n = (n) => {
3
+ t.dispatchEvent(new CustomEvent(e, { detail: n }));
4
+ }, r = (n) => {
5
+ let r = (e) => {
6
+ n(e.detail);
7
+ };
8
+ return t.addEventListener(e, r), () => {
9
+ t.removeEventListener(e, r);
10
+ };
11
+ };
12
+ //#endregion
13
+ export { n as emitToolsetLoginSuccess, r as subscribeToolsetLoginSuccess };
package/sharing.js CHANGED
@@ -1,3 +1,3 @@
1
- import { n as e, t } from "./useShareRecipientsCount-BgwCLKY0.js";
2
- import { t as n } from "./useShareLink-xkiaxATt.js";
3
- export { t as RecipientsCountStatus, n as useShareLink, e as useShareRecipientsCount };
1
+ import { RecipientsCountStatus as e, useShareRecipientsCount as t } from "./useShareRecipientsCount/useShareRecipientsCount.js";
2
+ import { useShareLink as n } from "./useShareLink/useShareLink.js";
3
+ export { e as RecipientsCountStatus, n as useShareLink, t as useShareRecipientsCount };
@@ -0,0 +1,48 @@
1
+ import { SKILL_FILE_UPLOAD_MAX_BYTES as e, isValidSkillRelativePath as t, parseSkillManifest as n } from "./skill.js";
2
+ import { formatFileSize as r } from "@epam/ai-dial-chat-shared";
3
+ import { SkillFileCandidateKind as i, SkillFileValidationStatus as a } from "@epam/ai-dial-skill-editor";
4
+ //#region src/skill/skill-file-batch-validation.ts
5
+ var o = async (o, s) => {
6
+ let { existingPaths: c, existingTotalBytes: l, manifestByteLength: u, messages: d } = s, f = [], p = [], m = new Set(c), h = /* @__PURE__ */ new Map();
7
+ for (let { path: e } of o) e !== "SKILL.md" && h.set(e, (h.get(e) ?? 0) + 1);
8
+ let g = 0, _ = /* @__PURE__ */ new Set(), v, y = u, b = 0;
9
+ for (let s of o) {
10
+ let { id: o, file: c, path: l } = s, u, p = i.SupportingFile;
11
+ if (l.toLowerCase() === "skill.md" && l !== "SKILL.md") u = d.manifestCasingInvalid;
12
+ else if (l === "SKILL.md") if (p = i.Manifest, b += 1, c.size > 1048576) u = d.fileTooLarge(r(e));
13
+ else try {
14
+ let e = await c.text();
15
+ if (e.includes("�")) u = d.manifestInvalidUtf8;
16
+ else {
17
+ let { frontmatter: t, instructions: r } = n(e), i = typeof t.name == "string" ? t.name : "", a = typeof t.description == "string" ? t.description : "";
18
+ !i.trim() || !a.trim() ? u = d.manifestInvalidFrontmatter : b === 1 && (v = {
19
+ candidateId: o,
20
+ name: i,
21
+ description: a,
22
+ frontmatter: t,
23
+ instructions: r
24
+ }, y = c.size);
25
+ }
26
+ } catch {
27
+ u = d.manifestInvalidFrontmatter;
28
+ }
29
+ else l ? t(l) ? m.has(l) || (h.get(l) ?? 0) > 1 ? u = d.pathDuplicate : c.size > 1048576 && (u = d.fileTooLarge(r(e))) : u = d.pathInvalid : u = d.required;
30
+ !u && p === i.SupportingFile && (_.add(l), g += c.size), f.push({
31
+ candidateId: o,
32
+ status: u ? a.Invalid : a.Valid,
33
+ kind: p,
34
+ error: u
35
+ });
36
+ }
37
+ if (b > 1) {
38
+ p.push({ message: d.manifestDuplicate }), v = void 0, y = u;
39
+ for (let e of f) e.kind === i.Manifest && !e.error && (e.status = a.Invalid, e.error = d.manifestDuplicate);
40
+ }
41
+ return l + g + y > 16777216 && p.push({ message: d.totalSizeExceeded }), m.size + _.size + 1 > 100 && p.push({ message: d.totalCountExceeded }), {
42
+ results: f,
43
+ batchErrors: p,
44
+ manifestCandidate: v
45
+ };
46
+ };
47
+ //#endregion
48
+ export { o as validateSkillFileBatch };
@@ -0,0 +1,15 @@
1
+ import { RequestStatus as e, getAttachmentTypeFromMime as t, inferMimeTypeFromPath as n } from "@epam/ai-dial-chat-shared";
2
+ //#region src/skill/skill-file-preview.ts
3
+ var r = (r, i) => {
4
+ let a = i.mimeType || n(r.path) || "", o = new File([new Uint8Array(i.bytes)], r.name, a ? { type: a } : void 0);
5
+ return {
6
+ id: r.path,
7
+ name: r.name,
8
+ contentType: a,
9
+ type: t(a),
10
+ status: e.Idle,
11
+ file: o
12
+ };
13
+ };
14
+ //#endregion
15
+ export { r as skillFileToAttachment };
@@ -0,0 +1,70 @@
1
+ import { parse as e } from "yaml";
2
+ //#region src/skill/skill-manifest.ts
3
+ var t = /^---[ \t]*$/, n = {
4
+ whenToUse: [
5
+ "when_to_use",
6
+ "when-to-use",
7
+ "whenToUse"
8
+ ],
9
+ allowedTools: [
10
+ "allowed_tools",
11
+ "allowed-tools",
12
+ "allowedTools"
13
+ ],
14
+ bundledResources: [
15
+ "bundled_resources",
16
+ "bundled-resources",
17
+ "bundledResources"
18
+ ],
19
+ skillPrompt: [
20
+ "skill_prompt",
21
+ "skill-prompt",
22
+ "skillPrompt"
23
+ ]
24
+ }, r = (e, t) => {
25
+ for (let n of t) {
26
+ let t = e[n];
27
+ if (typeof t == "string" && t !== "") return t;
28
+ }
29
+ }, i = (e, t) => {
30
+ for (let n of t) {
31
+ let t = e[n];
32
+ if (typeof t == "string" && t !== "") return [t];
33
+ if (!Array.isArray(t)) continue;
34
+ let r = t.filter((e) => typeof e == "string" && e !== "");
35
+ if (r.length > 0) return r;
36
+ }
37
+ }, a = (e) => {
38
+ let t = {}, a = r(e, n.whenToUse);
39
+ a != null && (t.whenToUse = a);
40
+ let o = i(e, n.allowedTools);
41
+ o != null && (t.allowedTools = o);
42
+ let s = i(e, n.bundledResources);
43
+ s != null && (t.bundledResources = s);
44
+ let c = r(e, n.skillPrompt);
45
+ return c != null && (t.skillPrompt = c), Object.keys(t).length > 0 ? t : void 0;
46
+ }, o = (n) => {
47
+ let i = n.replace(/^\uFEFF/, "").replace(/\r\n/g, "\n").split("\n"), o = i.findIndex((e) => e.trim() !== "");
48
+ if (o === -1 || !t.test(i[o].trim())) return { body: n };
49
+ let s = i.findIndex((e, n) => n > o && t.test(e.trim()));
50
+ if (s === -1) return { body: n };
51
+ let c;
52
+ try {
53
+ c = e(i.slice(o + 1, s).join("\n"));
54
+ } catch {
55
+ return { body: n };
56
+ }
57
+ let l = i.slice(s + 1);
58
+ l[0] === "" && l.shift();
59
+ let u = l.join("\n");
60
+ if (typeof c != "object" || !c) return { body: u };
61
+ let d = c, f = r(d, ["name"]), p = r(d, ["description"]), m = a(d);
62
+ return {
63
+ ...f == null ? {} : { name: f },
64
+ ...p == null ? {} : { description: p },
65
+ ...m == null ? {} : { about: m },
66
+ body: u
67
+ };
68
+ };
69
+ //#endregion
70
+ export { o as parseSkillManifestDocument };
@@ -0,0 +1,15 @@
1
+ //#region src/skill/skill-types.ts
2
+ var e = /* @__PURE__ */ function(e) {
3
+ return e.Personal = "personal", e.SharedWithMe = "sharedWithMe", e.Public = "public", e;
4
+ }({}), t = "public", n = "skills/", r = 256 * 1024, i = 1e3, a = 10, o = (e) => {
5
+ if (!e.startsWith(n)) return null;
6
+ let t = e.slice(7), r = t.indexOf("/");
7
+ if (r <= 0) return null;
8
+ let i = t.slice(0, r), a = t.slice(r + 1);
9
+ return i === "" || a === "" ? null : {
10
+ bucket: i,
11
+ path: a
12
+ };
13
+ };
14
+ //#endregion
15
+ export { t as PUBLIC_SKILL_BUCKET, a as SKILL_LISTING_MAX_PAGES, i as SKILL_LISTING_PAGE_SIZE, r as SKILL_MANIFEST_MAX_BYTES, e as SkillSource, o as parseSkillResourceUrl };
package/skill/skill.js ADDED
@@ -0,0 +1,48 @@
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";
4
+ //#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;
7
+ 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(/^-+|-+$/g, ""), m = ({ name: e, description: t, instructions: n }) => `---\n${r({
10
+ name: e,
11
+ description: t
12
+ }).trimEnd()}\n---\n\n${n}`, h = (e, t, n, i) => `---\n${r({
13
+ ...e,
14
+ name: t,
15
+ 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);
18
+ if (!t) throw Error("SKILL.md is missing its YAML frontmatter block");
19
+ let [, r, i] = t;
20
+ return {
21
+ frontmatter: n(r) ?? {},
22
+ instructions: i.replace(/^\r?\n/, "")
23
+ };
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);
29
+ return {
30
+ manifestText: new TextDecoder().decode(r),
31
+ files: a
32
+ };
33
+ }, y = (e) => {
34
+ let t = e.lastIndexOf("/");
35
+ 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({
37
+ name: t,
38
+ description: n,
39
+ instructions: r
40
+ }), S = (t, n) => {
41
+ let r = t.filter((t) => t.kind === e.File);
42
+ return {
43
+ filePaths: r.map((e) => e.path),
44
+ files: r.map((e) => b(n.get(e.path)?.bytes ?? new Uint8Array()))
45
+ };
46
+ };
47
+ //#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 };
@@ -0,0 +1,103 @@
1
+ import { getApiErrorStatus as e } from "../api-error/api-error.js";
2
+ import { stripSurroundingSlashes as t } from "../shared/string-utils.js";
3
+ import { SKILL_MANIFEST_FILE as n, nameFromPath as r, parseSkillManifest as i, unpackSkillArchive as a } from "./skill.js";
4
+ import { useEffect as o, useRef as s, useState as c } from "react";
5
+ import { SkillFileNodeKind as l } from "@epam/ai-dial-skill-editor";
6
+ //#region src/skill/useSkillEditorLoad.ts
7
+ var u = /* @__PURE__ */ function(e) {
8
+ return e.Loading = "loading", e.Loaded = "loaded", e.Error = "error", e.Forbidden = "forbidden", e.NotFound = "not-found", e;
9
+ }({}), d = class extends Error {}, f = (e, n) => {
10
+ let r = e.parentPath ? t(e.parentPath) : "", i = `${n.replace(/\/+$/g, "")}/files`;
11
+ return r === i ? e.name : r.startsWith(`${i}/`) ? `${r.slice(i.length + 1)}/${e.name}` : r === "files" ? e.name : r.startsWith("files/") ? `${r.slice(6)}/${e.name}` : null;
12
+ }, p = async (e, t, n) => {
13
+ let r = await e.downloadSkill(t, n), i = r.headers.get("etag");
14
+ if (!i) throw new d("Skill ETag is missing");
15
+ try {
16
+ let e = await r.arrayBuffer(), { manifestText: t, files: n } = a(new Uint8Array(e));
17
+ return {
18
+ etag: i,
19
+ manifestText: t,
20
+ files: n
21
+ };
22
+ } catch {
23
+ throw new d("Skill ZIP is invalid");
24
+ }
25
+ }, m = async (e, t, r) => {
26
+ let [i, a] = await Promise.all([e.downloadSkillFile(t, r, n), e.listSkillFiles({
27
+ bucket: t,
28
+ path: r,
29
+ filePath: "",
30
+ recursive: !0
31
+ })]), o = a.items.find((e) => e.nodeType === "item" && f(e, r) === "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: f(e, r)
36
+ })).filter((e) => e.path != null && e.path !== "SKILL.md"), l = await Promise.all(c.map(async ({ path: n }) => {
37
+ let i = await e.downloadSkillFile(t, r, n);
38
+ return [n, new Uint8Array(await i.arrayBuffer())];
39
+ }));
40
+ return {
41
+ etag: s,
42
+ manifestText: await i.text(),
43
+ files: new Map(l)
44
+ };
45
+ }, h = ({ isEditMode: t, bucket: n, skillPath: a, client: u }) => {
46
+ let [f, h] = c(t ? "loading" : "loaded"), [g, _] = c(0), [v, y] = c(), b = s(void 0), x = s({}), S = s(void 0), [C, w] = c([]), T = s(/* @__PURE__ */ new Map());
47
+ return o(() => {
48
+ if (!t || !n) return;
49
+ if (a == null) {
50
+ h("error");
51
+ return;
52
+ }
53
+ let o = !1;
54
+ return h("loading"), (async () => {
55
+ if (await Promise.resolve(), !o) try {
56
+ let t;
57
+ try {
58
+ t = await p(u, n, a);
59
+ } catch (r) {
60
+ let i = e(r);
61
+ if (!(r instanceof d) && i !== 400) throw r;
62
+ t = await m(u, n, a);
63
+ }
64
+ let { frontmatter: s, instructions: c } = i(t.manifestText);
65
+ if (o) return;
66
+ b.current = t.etag, x.current = s, S.current = a, T.current = new Map([...t.files].map(([e, t]) => [e, { bytes: t }])), w([...t.files.keys()].map((e) => ({
67
+ path: e,
68
+ name: r(e),
69
+ kind: l.File
70
+ }))), y({
71
+ name: typeof s.name == "string" ? s.name : "",
72
+ description: typeof s.description == "string" ? s.description : "",
73
+ instructions: c
74
+ }), h("loaded");
75
+ } catch (t) {
76
+ if (o) return;
77
+ let n = e(t);
78
+ h(n === 403 ? "forbidden" : n === 404 ? "not-found" : "error");
79
+ }
80
+ })(), () => {
81
+ o = !0;
82
+ };
83
+ }, [
84
+ t,
85
+ n,
86
+ a,
87
+ g,
88
+ u
89
+ ]), {
90
+ loadState: f,
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)
100
+ };
101
+ };
102
+ //#endregion
103
+ export { u as SkillEditorLoadState, h as useSkillEditorLoad };
@@ -0,0 +1,135 @@
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";
5
+ //#region src/skill/useSkillEditorSubmit.ts
6
+ var u = (e, t) => JSON.stringify({
7
+ values: e,
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) => {
11
+ switch (t(n)) {
12
+ case 409:
13
+ T({ name: x.nameConflict });
14
+ return;
15
+ case 412:
16
+ T({ name: x.nameConflict });
17
+ return;
18
+ case 413:
19
+ D(x.archiveTooLarge);
20
+ return;
21
+ case 503:
22
+ D(x.serviceUnavailable);
23
+ return;
24
+ case 400: {
25
+ let { message: t } = await e(n);
26
+ D(t ?? x.pathInvalid);
27
+ return;
28
+ }
29
+ default: {
30
+ let { traceId: t } = await e(n);
31
+ D(x.saveError), C({
32
+ variant: l.Error,
33
+ message: x.saveError,
34
+ requestId: t
35
+ });
36
+ }
37
+ }
38
+ }, [x, C]), P = o(async (e) => {
39
+ let t = a(e.name);
40
+ if (!t || !i(t)) {
41
+ T({ name: x.nameInvalid });
42
+ return;
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
52
+ };
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);
59
+ } catch (e) {
60
+ j("failure"), await N(e);
61
+ }
62
+ }, [
63
+ d,
64
+ p,
65
+ m,
66
+ h,
67
+ x,
68
+ b,
69
+ C,
70
+ 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);
78
+ return;
79
+ }
80
+ let o = r(h.current, e.name, e.description, e.instructions), { filePaths: s, files: c } = n(p, m.current);
81
+ j("submitting");
82
+ 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);
88
+ } catch (e) {
89
+ if (j("failure"), t(e) === 412) {
90
+ k({ message: x.conflictMessage });
91
+ return;
92
+ }
93
+ await N(e);
94
+ }
95
+ }, [
96
+ d,
97
+ p,
98
+ m,
99
+ h,
100
+ g,
101
+ _,
102
+ x,
103
+ b,
104
+ C,
105
+ S,
106
+ v,
107
+ y,
108
+ N
109
+ ]);
110
+ 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
+ ])
132
+ };
133
+ };
134
+ //#endregion
135
+ export { d as useSkillEditorSubmit };
@@ -0,0 +1,99 @@
1
+ import { SKILL_MANIFEST_FILE as e, buildSkillManifest as t, buildSkillManifestFromFrontmatter as n, nameFromPath as r } from "./skill.js";
2
+ import { validateSkillFileBatch as i } from "./skill-file-batch-validation.js";
3
+ import { getUtf8ByteLength as a } from "@epam/ai-dial-chat-shared";
4
+ import { useCallback as o, useMemo as s, useRef as c, useState as l } from "react";
5
+ import { SkillFileNodeKind as u } from "@epam/ai-dial-skill-editor";
6
+ //#region src/skill/useSkillFileActions.ts
7
+ var d = ({ files: d, setFiles: f, filesContentRef: p, frontmatterRef: m, loadedValues: h, setLoadedValues: g, isEditMode: _, isDirty: v, setSelectedPath: y, messages: b }) => {
8
+ let [x, S] = l(!1), C = c(null), w = o(() => {
9
+ let e = d.filter((e) => e.kind === u.File).map((e) => e.path), r = 0;
10
+ for (let t of e) r += p.current.get(t)?.bytes.length ?? 0;
11
+ let i = {
12
+ name: h?.name ?? "",
13
+ description: h?.description ?? "",
14
+ instructions: h?.instructions ?? ""
15
+ }, o = _ ? n(m.current, i.name, i.description, i.instructions) : t(i);
16
+ return {
17
+ existingPaths: e,
18
+ existingTotalBytes: r,
19
+ manifestByteLength: a(o),
20
+ messages: b
21
+ };
22
+ }, [
23
+ d,
24
+ p,
25
+ _,
26
+ m,
27
+ h,
28
+ b
29
+ ]), T = o(() => new Promise((e) => {
30
+ C.current = e, S(!0);
31
+ }), []), E = o((e) => {
32
+ S(!1), C.current?.(e), C.current = null;
33
+ }, []);
34
+ return {
35
+ fileActions: s(() => ({
36
+ validateBatch: async (e) => {
37
+ let { results: t, batchErrors: n } = await i(e, w());
38
+ return {
39
+ results: t,
40
+ batchErrors: n
41
+ };
42
+ },
43
+ commitBatch: async (e) => {
44
+ let { results: t, batchErrors: n, manifestCandidate: a } = await i(e, w());
45
+ if (t.some((e) => e.error !== void 0) || n.length > 0) return { error: n[0]?.message ?? b.saveError };
46
+ if (a) {
47
+ if (_ && a.name !== (h?.name ?? "")) return { error: b.manifestNameMismatch };
48
+ if ((_ || v) && !await T()) return { error: b.manifestImportDeclined };
49
+ }
50
+ try {
51
+ let t = e.filter((e) => e.id !== a?.candidateId), n = await Promise.all(t.map(async (e) => ({
52
+ path: e.path,
53
+ bytes: new Uint8Array(await e.file.arrayBuffer()),
54
+ mimeType: e.file.type || void 0
55
+ })));
56
+ for (let e of n) p.current.set(e.path, {
57
+ bytes: e.bytes,
58
+ mimeType: e.mimeType
59
+ });
60
+ return n.length > 0 && f((e) => [...e, ...n.map((e) => ({
61
+ path: e.path,
62
+ name: r(e.path),
63
+ kind: u.File
64
+ }))]), a && (m.current = _ ? {
65
+ ...m.current,
66
+ ...a.frontmatter
67
+ } : a.frontmatter, g({
68
+ name: _ ? h?.name ?? a.name : a.name,
69
+ description: a.description,
70
+ instructions: a.instructions
71
+ })), {};
72
+ } catch (e) {
73
+ return { error: e instanceof Error ? e.message : String(e) };
74
+ }
75
+ },
76
+ onRemoveNode: (t) => {
77
+ f((e) => e.filter((e) => e.path !== t && !e.path.startsWith(`${t}/`)));
78
+ for (let e of [...p.current.keys()]) (e === t || e.startsWith(`${t}/`)) && p.current.delete(e);
79
+ y((n) => n === t || n.startsWith(`${t}/`) ? e : n);
80
+ }
81
+ }), [
82
+ w,
83
+ _,
84
+ v,
85
+ h,
86
+ T,
87
+ p,
88
+ m,
89
+ f,
90
+ g,
91
+ y,
92
+ b
93
+ ]),
94
+ pendingManifestImport: x,
95
+ resolveManifestImport: E
96
+ };
97
+ };
98
+ //#endregion
99
+ export { d as useSkillFileActions };
@@ -0,0 +1,29 @@
1
+ import { useEffect as e, useState as t } from "react";
2
+ //#region src/skill/useSkillFilePreview.ts
3
+ var n = /* @__PURE__ */ function(e) {
4
+ return e.Forbidden = "forbidden", e.Generic = "generic", e;
5
+ }({}), r = ({ fileId: n, onLoadFile: r }) => {
6
+ let [i, a] = t(!1), [o, s] = t(null), [c, l] = t(null);
7
+ return e(() => {
8
+ let e = !1;
9
+ return a(!0), s(null), l(null), (async () => {
10
+ try {
11
+ let t = await r(n);
12
+ if (e) return;
13
+ s(t), a(!1);
14
+ } catch (t) {
15
+ if (e) return;
16
+ let n = t.status;
17
+ l(n === 403 ? "forbidden" : "generic"), a(!1);
18
+ }
19
+ })(), () => {
20
+ e = !0;
21
+ };
22
+ }, [n, r]), {
23
+ isLoading: i,
24
+ content: o,
25
+ error: c
26
+ };
27
+ };
28
+ //#endregion
29
+ export { n as SkillPreviewErrorKind, r as useSkillFilePreview };
@@ -49,4 +49,4 @@ var i = ({ listSkills: i, enabled: a, ready: o }) => {
49
49
  ]);
50
50
  };
51
51
  //#endregion
52
- export { i as t };
52
+ export { i as useSkillsState };
package/skill-editor.js CHANGED
@@ -1,3 +1,8 @@
1
- import { a as e, c as t, d as n, f as r, h as i, i as a, l as o, m as s, n as c, o as l, p as u, r as d, s as f, t as p, u as m } from "./skill-manifest-CeG6-WSK.js";
2
- import { a as h, i as g, n as _, o as v, r as y, t as b } from "./useSkillFileActions-B-VaGD20.js";
3
- export { c as SKILL_FILE_UPLOAD_MAX_BYTES, d as SKILL_MANIFEST_FILE, a as SKILL_UPLOAD_MAX_FILES, e as SKILL_UPLOAD_MAX_TOTAL_BYTES, y as SkillEditorLoadState, l as buildSkillFilesPayload, f as buildSkillManifest, t as buildSkillManifestForSubmit, o as buildSkillManifestFromFrontmatter, m as isValidSkillRelativePath, n as nameFromPath, r as normalizeSkillName, u as parseSkillManifest, p as parseSkillManifestDocument, s as skillFileBytesToBlob, h as skillFileToAttachment, i as unpackSkillArchive, g as useSkillEditorLoad, _ as useSkillEditorSubmit, b as useSkillFileActions, v as validateSkillFileBatch };
1
+ import { SKILL_FILE_UPLOAD_MAX_BYTES as e, SKILL_MANIFEST_FILE as t, SKILL_UPLOAD_MAX_FILES as n, SKILL_UPLOAD_MAX_TOTAL_BYTES as r, buildSkillFilesPayload as i, buildSkillManifest as a, buildSkillManifestForSubmit as o, buildSkillManifestFromFrontmatter as s, isValidSkillRelativePath as c, nameFromPath as l, normalizeSkillName as u, parseSkillManifest as d, skillFileBytesToBlob as f, unpackSkillArchive as p } from "./skill/skill.js";
2
+ import { parseSkillManifestDocument as m } from "./skill/skill-manifest.js";
3
+ import { validateSkillFileBatch as h } from "./skill/skill-file-batch-validation.js";
4
+ import { skillFileToAttachment as g } from "./skill/skill-file-preview.js";
5
+ import { SkillEditorLoadState as _, useSkillEditorLoad as v } from "./skill/useSkillEditorLoad.js";
6
+ import { useSkillEditorSubmit as y } from "./skill/useSkillEditorSubmit.js";
7
+ import { useSkillFileActions as b } from "./skill/useSkillFileActions.js";
8
+ export { e as SKILL_FILE_UPLOAD_MAX_BYTES, t as SKILL_MANIFEST_FILE, n as SKILL_UPLOAD_MAX_FILES, r as SKILL_UPLOAD_MAX_TOTAL_BYTES, _ as SkillEditorLoadState, i as buildSkillFilesPayload, a as buildSkillManifest, o as buildSkillManifestForSubmit, s as buildSkillManifestFromFrontmatter, c as isValidSkillRelativePath, l as nameFromPath, u as normalizeSkillName, d as parseSkillManifest, m as parseSkillManifestDocument, f as skillFileBytesToBlob, g as skillFileToAttachment, p as unpackSkillArchive, v as useSkillEditorLoad, y as useSkillEditorSubmit, b as useSkillFileActions, h as validateSkillFileBatch };
package/skills-state.js CHANGED
@@ -1,2 +1,2 @@
1
- import { t as e } from "./useSkillsState-BoLlwmzb.js";
1
+ import { useSkillsState as e } from "./skill/useSkillsState/useSkillsState.js";
2
2
  export { e as useSkillsState };
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Returns the last path segment of `url` — its file name — for both absolute
3
+ * URLs and DIAL-relative resource paths such as
4
+ * `files/<bucket>/qa-routed-source.html`. Any query string or hash is dropped
5
+ * and percent escapes are decoded. Returns an empty string when no segment can
6
+ * be extracted. Used to classify a resource by extension when its display name
7
+ * is a citation title rather than a file name.
8
+ */
9
+ export declare const getUrlFileName: (url: string) => string;
10
+
11
+ /** Returns true when an external (non-DIAL) source URL should be opened in the canvas rather than a new browser tab. */
12
+ export declare const isExternalSourcePreviewable: (contentType: string, url: string) => boolean;
13
+
14
+ /**
15
+ * Returns the content type to trust for an external citation source: `contentType`
16
+ * unchanged when it is already an image/audio/PDF/document-renderer marker,
17
+ * otherwise the type implied by `url`'s path extension (`application/pdf` for
18
+ * `.pdf`, the canonical MIME for `.docx`/`.xlsx`/`.pptx`/`.csv`) when that
19
+ * extension is recognized, otherwise `contentType` unchanged.
20
+ *
21
+ * Web-search grounding APIs label every reference — PDFs and Office documents
22
+ * included — as `text/markdown`, so a mislabeled `contentType` must not win
23
+ * over a recognized URL extension: doing so previously sent a PDF's raw bytes
24
+ * into the markdown/text canvas viewer, rendering garbled text instead of
25
+ * opening the PDF/OOXML viewer.
26
+ */
27
+ export declare const resolveExternalSourceContentType: (contentType: string, url: string) => string;
28
+
29
+ export { }