@epam/ai-dial-chat-hooks 1.2.0-dev.20 → 1.2.0-dev.207

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 (89) hide show
  1. package/api-error/api-error.js +5 -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-input.js +81 -9
  7. package/catalog/map-deployment-to-catalog-item.js +34 -34
  8. package/catalog/map-entity-details-to-catalog.js +7 -0
  9. package/catalog/map-skill-to-catalog-item.js +30 -27
  10. package/catalog/publish.js +6 -5
  11. package/catalog/useApplicationCredentials/useApplicationCredentials.js +39 -0
  12. package/catalog/useSkillDetailsPanelData/useSkillDetailsPanelData.js +39 -39
  13. package/catalog/useSkillItemDetails.js +17 -13
  14. package/catalog.d.ts +116 -20
  15. package/catalog.js +23 -22
  16. package/conversation/conversation-transfer/export-conversation.js +24 -16
  17. package/conversation/conversation-transfer/import-conversation.js +80 -31
  18. package/conversation/conversation-transfer/queue.js +8 -5
  19. package/conversation/create-chat-stream-api.js +85 -49
  20. package/conversation/message-utils.js +44 -2
  21. package/conversation/stage.js +23 -0
  22. package/conversation/useConversationExport/useConversationExport.js +9 -9
  23. package/conversation/useConversationHandlers/useConversationHandlers.js +16 -5
  24. package/conversation/useConversationImport/useConversationImport.js +123 -121
  25. package/conversation/useConversationPanelItems/useConversationPanelItems.js +2 -3
  26. package/conversation/useConversationScroll/useConversationScroll.js +68 -64
  27. package/conversation/useConversationStream/apply-chunk.js +1 -1
  28. package/conversation/useConversationStream/generation-resume.js +104 -63
  29. package/conversation/useConversationStream/useConversationStream.js +183 -108
  30. package/conversation/useMessageSelectionReply/useMessageSelectionReply.js +189 -0
  31. package/conversation-overlay.d.ts +7 -0
  32. package/conversation-overlay.js +2 -0
  33. package/conversation-sources/useConversationSources/useConversationSources.js +31 -24
  34. package/conversation-sources.d.ts +1 -1
  35. package/conversation-transfer.d.ts +2 -1
  36. package/conversation.d.ts +241 -13
  37. package/conversation.js +32 -30
  38. package/file-manager-canvas.d.ts +398 -0
  39. package/file-manager-canvas.js +2 -0
  40. package/file-manager.d.ts +153 -350
  41. package/file-manager.js +25 -24
  42. package/files/attachment-canvas.js +40 -1
  43. package/files/attachment-types.js +14 -13
  44. package/files/dial-file-manager-mapping.util.js +2 -1
  45. package/files/dial-file-manager-path.util.js +23 -1
  46. package/files/dial-file-manager.model.js +23 -19
  47. package/files/dial-file-manager.types.js +3 -3
  48. package/files/useDialFileListing/useDialFileListing.js +157 -145
  49. package/files/useDialFileManager/useDialFileManager.js +132 -128
  50. package/files/useDialFileManagerSections/useDialFileManagerSections.js +155 -0
  51. package/files/useDialFileManagerTabConfig/useDialFileManagerTabConfig.js +20 -19
  52. package/files/useDialFileMutations/useDialFileMutations.js +33 -32
  53. package/files/useDialFileUploadBatch/useDialFileUploadBatch.js +117 -110
  54. package/files/useFileAttachmentPicker/useFileAttachmentPicker.js +43 -0
  55. package/index.d.ts +1068 -81
  56. package/index.js +136 -122
  57. package/mcp-apps/useMcpAppHostAdapter/useMcpAppHostAdapter.js +7 -5
  58. package/mcp-apps/useMcpAppHostContext/useMcpAppHostContext.js +1 -1
  59. package/mcp-apps/useMcpAppTools/useMcpAppTools.js +1 -1
  60. package/mcp-apps/useOpenMcpAppCanvas/useOpenMcpAppCanvas.js +25 -23
  61. package/mcp-apps.d.ts +8 -6
  62. package/oauth/toolset-id.js +5 -3
  63. package/oauth/useToolsetLogin/useToolsetLogin.js +8 -8
  64. package/oauth.d.ts +32 -0
  65. package/oauth.js +9 -9
  66. package/package.json +36 -21
  67. package/scheduled-task/scheduled-task-description.js +77 -0
  68. package/scheduled-task/scheduled-task-preparation.js +24 -0
  69. package/scheduled-task/scheduled-task-trigger.js +7 -2
  70. package/scheduled-task/scheduled-tasks-api-client.js +19 -0
  71. package/scheduled-task/use-scheduled-task-runs.js +194 -0
  72. package/scheduled-task/use-scheduled-tasks.js +93 -0
  73. package/scheduled-tasks.d.ts +195 -3
  74. package/scheduled-tasks.js +7 -2
  75. package/skill/skill-archive.js +19 -0
  76. package/skill/skill-types.js +8 -7
  77. package/skill/skill.js +42 -27
  78. package/skill/useSkillArchiveImport/useSkillArchiveImport.js +79 -0
  79. package/skill/useSkillEditorLoad.js +29 -28
  80. package/skill/useSkillEditorSubmit.js +108 -84
  81. package/skill/useSkillFileActions.js +70 -58
  82. package/skill-editor.d.ts +133 -3
  83. package/skill-editor.js +9 -8
  84. package/usage/map-usage-data-to-dashboard.js +66 -0
  85. package/usage/map-user-usage-to-model-limits.js +202 -0
  86. package/usage.d.ts +125 -0
  87. package/usage.js +3 -0
  88. package/usePageFileDrag/usePageFileDrag.js +3 -3
  89. package/utils.d.ts +8 -6
@@ -1,8 +1,33 @@
1
+ import { CreatedScheduledTaskDto } from '@epam/ai-dial-chat-api-client';
1
2
  import { CreateScheduledTaskBodyDto } from '@epam/ai-dial-chat-api-client';
3
+ import { Dispatch } from 'react';
4
+ import { ListScheduledTaskRunsResponseDto } from '@epam/ai-dial-chat-api-client';
5
+ import { ListScheduledTasksResponseDto } from '@epam/ai-dial-chat-api-client';
6
+ import { ListScheduledTasksSortEnum } from '@epam/ai-dial-chat-api-client';
2
7
  import { ScheduledTaskCreateFormValues } from '@epam/ai-dial-scheduled-tasks';
3
8
  import { ScheduledTaskDto } from '@epam/ai-dial-chat-api-client';
9
+ import { ScheduledTaskRunDto } from '@epam/ai-dial-chat-api-client';
10
+ import { ScheduledTaskValidationErrors } from '../../libs/scheduled-tasks/validation';
11
+ import { ScheduledTaskValidationOptions } from '../../libs/scheduled-tasks/validation';
12
+ import { ScheduleTriggerDto } from '@epam/ai-dial-chat-api-client';
13
+ import { SetStateAction } from 'react';
14
+ import { UpdatedScheduledTaskDto } from '@epam/ai-dial-chat-api-client';
4
15
  import { UpdateScheduledTaskBodyDto } from '@epam/ai-dial-chat-api-client';
5
16
 
17
+ /**
18
+ * Composes scheduler operations over an already configured generated client.
19
+ * Authentication, base URL, CSRF, and retries remain host responsibilities.
20
+ */
21
+ export declare const createScheduledTasksApiClient: (client: ScheduledTasksConfiguredClient) => ScheduledTasksApiClient;
22
+
23
+ /**
24
+ * Describes the complete trigger without requiring unrelated task metadata.
25
+ * Unsupported constraints remain Custom, with the full source expression.
26
+ * Calendar-month shifts crossing month boundaries or days 29–31 remain
27
+ * Custom because a shifted monthly day is not equivalent around short months.
28
+ */
29
+ export declare const describeScheduledTaskTrigger: (trigger: ScheduleTriggerDto, { timeZone, referenceDate, }?: ScheduledTaskTriggerDescriptionOptions) => ScheduledTaskTriggerDescription;
30
+
6
31
  /**
7
32
  * Maps validated create-form values to the `POST /api/v1/scheduled-tasks`
8
33
  * request body, building `trigger.date` for a one-shot schedule or
@@ -13,9 +38,8 @@ import { UpdateScheduledTaskBodyDto } from '@epam/ai-dial-chat-api-client';
13
38
  export declare const mapFormValuesToCreateBody: (values: ScheduledTaskCreateFormValues) => CreateScheduledTaskBodyDto;
14
39
 
15
40
  /**
16
- * Maps validated edit-form values to the `PUT /api/v1/scheduled-tasks/:scheduleId`
17
- * request body. `UpdateScheduledTaskBodyDto` has the same shape as
18
- * `CreateScheduledTaskBodyDto`, so this reuses the same trigger-building logic.
41
+ * Maps a complete, validated edit draft to an update body. An unset skill
42
+ * emits null to remove the saved reference; hydrate from detail before editing.
19
43
  */
20
44
  export declare const mapFormValuesToUpdateBody: (values: ScheduledTaskCreateFormValues) => UpdateScheduledTaskBodyDto;
21
45
 
@@ -29,6 +53,24 @@ export declare const mapFormValuesToUpdateBody: (values: ScheduledTaskCreateForm
29
53
  */
30
54
  export declare const mapScheduledTaskDtoToFormValues: (dto: ScheduledTaskDto) => ScheduledTaskDtoMappingResult;
31
55
 
56
+ /**
57
+ * Merges a freshly-fetched page 0 into the currently-loaded run list: an
58
+ * already-known id is replaced in place at its existing array position, an
59
+ * unseen id is prepended (upstream order is `created_at desc`, so it is the
60
+ * newest), and an id absent from `incoming` is left untouched — a background
61
+ * refresh never removes a loaded run.
62
+ */
63
+ export declare const mergeRunsById: (current: ScheduledTaskRunDto[], incoming: ScheduledTaskRunDto[]) => ScheduledTaskRunDto[];
64
+
65
+ /**
66
+ * Validates form values before creating a request body. Hosts translate the
67
+ * returned field codes and must not issue a write when `ok` is false.
68
+ */
69
+ export declare const prepareScheduledTaskCreateBody: (values: ScheduledTaskCreateFormValues, options: ScheduledTaskValidationOptions) => ScheduledTaskPreparationResult<CreateScheduledTaskBodyDto>;
70
+
71
+ /** Validates form values before preparing an update request body. */
72
+ export declare const prepareScheduledTaskUpdateBody: (values: ScheduledTaskCreateFormValues, options: ScheduledTaskValidationOptions) => ScheduledTaskPreparationResult<UpdateScheduledTaskBodyDto>;
73
+
32
74
  /** Result of mapping a scheduled task DTO back to editable form values. */
33
75
  export declare type ScheduledTaskDtoMappingResult = {
34
76
  ok: true;
@@ -38,6 +80,106 @@ export declare type ScheduledTaskDtoMappingResult = {
38
80
  reason: UnsupportedTriggerReason;
39
81
  };
40
82
 
83
+ /** A checked request preparation result that never serializes invalid values. */
84
+ export declare type ScheduledTaskPreparationResult<TBody> = {
85
+ ok: true;
86
+ body: TBody;
87
+ } | {
88
+ ok: false;
89
+ errors: ScheduledTaskValidationErrors;
90
+ };
91
+
92
+ export declare interface ScheduledTaskRunsListRequest {
93
+ scheduleId: string;
94
+ limit?: number;
95
+ offset?: number;
96
+ signal?: AbortSignal;
97
+ }
98
+
99
+ export declare interface ScheduledTasksApiClient {
100
+ listScheduledTasks: (request?: ScheduledTasksListRequest) => Promise<ListScheduledTasksResponseDto>;
101
+ listScheduledTaskRuns: (request: ScheduledTaskRunsListRequest) => Promise<ListScheduledTaskRunsResponseDto>;
102
+ createScheduledTask: (body: CreateScheduledTaskBodyDto) => Promise<CreatedScheduledTaskDto>;
103
+ getScheduledTask: (scheduleId: string) => Promise<ScheduledTaskDto>;
104
+ updateScheduledTask: (scheduleId: string, body: UpdateScheduledTaskBodyDto) => Promise<UpdatedScheduledTaskDto>;
105
+ pauseScheduledTask: (scheduleId: string) => Promise<ScheduledTaskDto>;
106
+ resumeScheduledTask: (scheduleId: string) => Promise<ScheduledTaskDto>;
107
+ deleteScheduledTask: (scheduleId: string) => Promise<void>;
108
+ }
109
+
110
+ /** Narrow configured generated-client surface required by scheduler hooks. */
111
+ export declare interface ScheduledTasksConfiguredClient {
112
+ listScheduledTasks: (request: {
113
+ limit?: number;
114
+ offset?: number;
115
+ search?: string;
116
+ sort?: ListScheduledTasksSortEnum;
117
+ }, options?: RequestInit) => Promise<ListScheduledTasksResponseDto>;
118
+ listScheduledTaskRuns: (request: {
119
+ scheduleId: string;
120
+ limit?: number;
121
+ offset?: number;
122
+ }, options?: RequestInit) => Promise<ListScheduledTaskRunsResponseDto>;
123
+ createScheduledTask: (request: {
124
+ createScheduledTaskBodyDto: CreateScheduledTaskBodyDto;
125
+ }) => Promise<CreatedScheduledTaskDto>;
126
+ getScheduledTask: (request: {
127
+ scheduleId: string;
128
+ }) => Promise<ScheduledTaskDto>;
129
+ updateScheduledTask: (request: {
130
+ scheduleId: string;
131
+ updateScheduledTaskBodyDto: UpdateScheduledTaskBodyDto;
132
+ }) => Promise<UpdatedScheduledTaskDto>;
133
+ pauseScheduledTask: (request: {
134
+ scheduleId: string;
135
+ }) => Promise<ScheduledTaskDto>;
136
+ resumeScheduledTask: (request: {
137
+ scheduleId: string;
138
+ }) => Promise<ScheduledTaskDto>;
139
+ deleteScheduledTask: (request: {
140
+ scheduleId: string;
141
+ }) => Promise<void>;
142
+ }
143
+
144
+ /** App-agnostic request options accepted by the scheduler facade. */
145
+ export declare interface ScheduledTasksListRequest {
146
+ limit?: number;
147
+ offset?: number;
148
+ search?: string;
149
+ sort?: ListScheduledTasksSortEnum;
150
+ signal?: AbortSignal;
151
+ }
152
+
153
+ export declare interface ScheduledTaskTriggerDescription {
154
+ kind: ScheduledTaskTriggerDescriptionKind;
155
+ time?: string;
156
+ dayOfWeek?: string;
157
+ dayOfMonth?: string;
158
+ intervalMinutes?: number;
159
+ date?: Date;
160
+ expression?: string;
161
+ sourceTimezone: 'utc';
162
+ }
163
+
164
+ /** Display categories are independent of task editability. */
165
+ export declare enum ScheduledTaskTriggerDescriptionKind {
166
+ OneTime = "oneTime",
167
+ Hourly = "hourly",
168
+ EveryNMinutes = "everyNMinutes",
169
+ Daily = "daily",
170
+ Weekly = "weekly",
171
+ Monthly = "monthly",
172
+ Custom = "custom",
173
+ Invalid = "invalid"
174
+ }
175
+
176
+ export declare interface ScheduledTaskTriggerDescriptionOptions {
177
+ /** Display timezone; defaults to UTC for backwards compatibility. */
178
+ timeZone?: string;
179
+ /** Date whose timezone offset is used. Defaults to now (the existing UTC-storage policy). */
180
+ referenceDate?: Date;
181
+ }
182
+
41
183
  /** Why a scheduled task DTO could not be mapped back to editable form values. */
42
184
  export declare enum UnsupportedTriggerReason {
43
185
  /** `trigger.cron.fields` uses a shape (extra keys, or both `day_of_week` and `day`) the editor's schedule controls cannot represent. */
@@ -48,4 +190,54 @@ export declare enum UnsupportedTriggerReason {
48
190
  MissingRequiredFields = "missingRequiredFields"
49
191
  }
50
192
 
193
+ /** Shared, cancellation-safe pagination and background refresh for one schedule's run history. */
194
+ export declare const useScheduledTaskRuns: (client: ScheduledTasksApiClient, { scheduleId, enabled, pageSize, nextRunTime, }: UseScheduledTaskRunsOptions) => {
195
+ items: ScheduledTaskRunDto[];
196
+ isLoading: boolean;
197
+ isLoadingMore: boolean;
198
+ initialError: Error | null;
199
+ loadMoreError: Error | null;
200
+ hasMore: boolean;
201
+ loadMore: () => void;
202
+ retryLoadMore: () => void;
203
+ refetch: () => void;
204
+ };
205
+
206
+ export declare interface UseScheduledTaskRunsOptions {
207
+ scheduleId: string;
208
+ enabled?: boolean;
209
+ pageSize?: number;
210
+ /**
211
+ * The task's next scheduled run time (ISO string), when known. Drives the
212
+ * one-shot background refresh described on {@link useScheduledTaskRuns}.
213
+ * The caller already holds the task DTO — this hook never fetches it.
214
+ */
215
+ nextRunTime?: string | null;
216
+ }
217
+
218
+ /** Shared scheduler-list lifecycle with generation-scoped stale-response guards. */
219
+ export declare const useScheduledTasks: (client: ScheduledTasksApiClient, { enabled, pageSize, debounceMs, initialSearch, initialSort, }?: UseScheduledTasksOptions) => {
220
+ items: ScheduledTaskDto[];
221
+ searchQuery: string;
222
+ setSearchQuery: Dispatch<SetStateAction<string>>;
223
+ sortKey: "firstToRun" | "lastToRun" | "newest" | "nameAZ";
224
+ setSortKey: Dispatch<SetStateAction<"firstToRun" | "lastToRun" | "newest" | "nameAZ">>;
225
+ isLoading: boolean;
226
+ isLoadingMore: boolean;
227
+ initialError: Error | null;
228
+ loadMoreError: Error | null;
229
+ hasMore: boolean;
230
+ loadMore: () => void;
231
+ retryLoadMore: () => void;
232
+ refetch: () => void;
233
+ };
234
+
235
+ export declare interface UseScheduledTasksOptions {
236
+ enabled?: boolean;
237
+ pageSize?: number;
238
+ debounceMs?: number;
239
+ initialSearch?: string;
240
+ initialSort?: ListScheduledTasksSortEnum;
241
+ }
242
+
51
243
  export { }
@@ -1,3 +1,8 @@
1
1
  import { UnsupportedTriggerReason as e } from "./scheduled-task/scheduled-task-mapping.js";
2
- import { mapFormValuesToCreateBody as t, mapFormValuesToUpdateBody as n, mapScheduledTaskDtoToFormValues as r } from "./scheduled-task/scheduled-task-trigger.js";
3
- export { e as UnsupportedTriggerReason, t as mapFormValuesToCreateBody, n as mapFormValuesToUpdateBody, r as mapScheduledTaskDtoToFormValues };
2
+ import { ScheduledTaskTriggerDescriptionKind as t, describeScheduledTaskTrigger as n } from "./scheduled-task/scheduled-task-description.js";
3
+ import { mapFormValuesToCreateBody as r, mapFormValuesToUpdateBody as i, mapScheduledTaskDtoToFormValues as a } from "./scheduled-task/scheduled-task-trigger.js";
4
+ import { prepareScheduledTaskCreateBody as o, prepareScheduledTaskUpdateBody as s } from "./scheduled-task/scheduled-task-preparation.js";
5
+ import { createScheduledTasksApiClient as c } from "./scheduled-task/scheduled-tasks-api-client.js";
6
+ import { useScheduledTasks as l } from "./scheduled-task/use-scheduled-tasks.js";
7
+ import { mergeRunsById as u, useScheduledTaskRuns as d } from "./scheduled-task/use-scheduled-task-runs.js";
8
+ export { t as ScheduledTaskTriggerDescriptionKind, e as UnsupportedTriggerReason, c as createScheduledTasksApiClient, n as describeScheduledTaskTrigger, r as mapFormValuesToCreateBody, i as mapFormValuesToUpdateBody, a as mapScheduledTaskDtoToFormValues, u as mergeRunsById, o as prepareScheduledTaskCreateBody, s as prepareScheduledTaskUpdateBody, d as useScheduledTaskRuns, l as useScheduledTasks };
@@ -0,0 +1,19 @@
1
+ import { nameFromPath as e } from "./skill.js";
2
+ import { inferMimeTypeFromPath as t } from "@epam/ai-dial-chat-shared";
3
+ import { unzipSync as n } from "fflate";
4
+ //#region src/skill/skill-archive.ts
5
+ var r = "__MACOSX/", i = ".DS_Store", a = (t) => t.endsWith("/") || t.startsWith(r) || e(t) === i, o = (e) => new Promise((t, n) => {
6
+ let r = new FileReader();
7
+ r.onload = () => t(new Uint8Array(r.result)), r.onerror = () => n(r.error), r.readAsArrayBuffer(e);
8
+ }), s = async (r) => {
9
+ let i = n(await o(r));
10
+ return Object.entries(i).flatMap(([n, r]) => {
11
+ let i = n.replace(/\\/g, "/");
12
+ return a(i) ? [] : [{
13
+ path: i,
14
+ file: new File([r], e(i), { type: t(i) ?? "" })
15
+ }];
16
+ });
17
+ };
18
+ //#endregion
19
+ export { s as extractSkillArchive };
@@ -1,15 +1,16 @@
1
+ import { PUBLIC_BUCKET as e } from "@epam/ai-dial-chat-shared";
1
2
  //#region src/skill/skill-types.ts
2
- var e = /* @__PURE__ */ function(e) {
3
+ var t = /* @__PURE__ */ function(e) {
3
4
  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);
5
+ }({}), n = e, r = "skills/", i = 256 * 1024, a = 1e3, o = 10, s = (e) => {
6
+ if (!e.startsWith(r)) return null;
7
+ let t = e.slice(7), n = t.indexOf("/");
8
+ if (n <= 0) return null;
9
+ let i = t.slice(0, n), a = t.slice(n + 1);
9
10
  return i === "" || a === "" ? null : {
10
11
  bucket: i,
11
12
  path: a
12
13
  };
13
14
  };
14
15
  //#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 };
16
+ export { n as PUBLIC_SKILL_BUCKET, o as SKILL_LISTING_MAX_PAGES, a as SKILL_LISTING_PAGE_SIZE, i as SKILL_MANIFEST_MAX_BYTES, t as SkillSource, s as parseSkillResourceUrl };
package/skill/skill.js CHANGED
@@ -1,48 +1,63 @@
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, exceedsMaxLength as r } from "@epam/ai-dial-chat-shared";
2
+ import { SkillFileNodeKind as i } from "@epam/ai-dial-skill-editor";
3
+ import { unzipSync as a } from "fflate";
4
+ import { parse as o, stringify as s } 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 c = "SKILL.md", l = 1048576, u = 16777216, d = 100, f = new Set([".dial-resource", ".dial-folder"]), p = new Set(["files", "v"]), m = /^[a-zA-Z]:/, h = /[\x00-\x1f]/, g = (e) => {
7
+ if (e === "" || e.startsWith("/") || m.test(e) || e.includes("\\") || h.test(e)) return !1;
7
8
  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({
9
+ return !(t.some((e) => e === "" || e === "." || e === "..") || t.some((e) => f.has(e)) || p.has(t[0]));
10
+ }, _ = (e) => e.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-/, "").replace(/-$/, ""), v = {
11
+ name: n,
12
+ description: e,
13
+ instructions: t
14
+ }, y = (e) => {
15
+ let t = {};
16
+ for (let n of Object.keys(v)) {
17
+ let i = v[n];
18
+ r(e[n].trim(), i) && (t[n] = i);
19
+ }
20
+ return t;
21
+ }, b = ({ name: e, description: t, instructions: n }) => `---\n${s({
10
22
  name: e,
11
23
  description: t
12
- }).trimEnd()}\n---\n\n${n}`, h = (e, t, n, i) => `---\n${r({
24
+ }).trimEnd()}\n---\n\n${n}`, x = (e, t, n, r) => `---\n${s({
13
25
  ...e,
14
26
  name: t,
15
27
  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);
28
+ }).trimEnd()}\n---\n\n${r}`, S = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/, C = /^---[ \t]*$/, w = (e) => {
29
+ let t = e.replace(/^\uFEFF/, "").replace(/\r\n/g, "\n").split("\n"), n = t.findIndex((e) => e.trim() !== "");
30
+ return n === -1 || !C.test(t[n]) ? !1 : t.some((e, t) => t > n && C.test(e));
31
+ }, T = (e) => {
32
+ let t = S.exec(e);
18
33
  if (!t) throw Error("SKILL.md is missing its YAML frontmatter block");
19
- let [, r, i] = t;
34
+ let [, n, r] = t;
20
35
  return {
21
- frontmatter: n(r) ?? {},
22
- instructions: i.replace(/^\r?\n/, "")
36
+ frontmatter: o(n) ?? {},
37
+ instructions: r.replace(/^\r?\n/, "")
23
38
  };
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);
39
+ }, E = (e) => {
40
+ let t = a(e), n = t[c];
41
+ if (n == null) throw Error(`Skill archive is missing a root ${c} file`);
42
+ let r = /* @__PURE__ */ new Map();
43
+ for (let [e, n] of Object.entries(t)) e === "SKILL.md" || e.endsWith("/") || r.set(e, n);
29
44
  return {
30
- manifestText: new TextDecoder().decode(r),
31
- files: a
45
+ manifestText: new TextDecoder().decode(n),
46
+ files: r
32
47
  };
33
- }, y = (e) => {
48
+ }, D = (e) => {
34
49
  let t = e.lastIndexOf("/");
35
50
  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({
51
+ }, O = (e) => new Blob([new Uint8Array(e)]), k = (e, t, n, r) => Object.keys(e).length > 0 ? x(e, t, n, r) : b({
37
52
  name: t,
38
53
  description: n,
39
54
  instructions: r
40
- }), S = (t, n) => {
41
- let r = t.filter((t) => t.kind === e.File);
55
+ }), A = (e, t) => {
56
+ let n = e.filter((e) => e.kind === i.File);
42
57
  return {
43
- filePaths: r.map((e) => e.path),
44
- files: r.map((e) => b(n.get(e.path)?.bytes ?? new Uint8Array()))
58
+ filePaths: n.map((e) => e.path),
59
+ files: n.map((e) => O(t.get(e.path)?.bytes ?? new Uint8Array()))
45
60
  };
46
61
  };
47
62
  //#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 };
63
+ export { l as SKILL_FILE_UPLOAD_MAX_BYTES, c as SKILL_MANIFEST_FILE, v as SKILL_TEXT_FIELD_MAX_LENGTHS, d as SKILL_UPLOAD_MAX_FILES, u as SKILL_UPLOAD_MAX_TOTAL_BYTES, A as buildSkillFilesPayload, b as buildSkillManifest, k as buildSkillManifestForSubmit, x as buildSkillManifestFromFrontmatter, y as getSkillFieldLengthViolations, g as isValidSkillRelativePath, D as nameFromPath, _ as normalizeSkillName, T as parseSkillManifest, O as skillFileBytesToBlob, w as startsWithFrontmatterBlock, E 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 };
@@ -6,12 +6,12 @@ import { SkillFileNodeKind as u } from "@epam/ai-dial-skill-editor";
6
6
  //#region src/skill/useSkillEditorLoad.ts
7
7
  var d = /* @__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
+ }({}), f = class extends Error {}, p = class extends Error {}, m = (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
+ }, h = 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 p("Skill ETag is missing");
15
15
  try {
16
16
  let e = await r.arrayBuffer(), { manifestText: t, files: n } = o(new Uint8Array(e));
17
17
  return {
@@ -22,17 +22,17 @@ var d = /* @__PURE__ */ function(e) {
22
22
  } catch {
23
23
  throw new f("Skill ZIP is invalid");
24
24
  }
25
- }, h = async (e, t, n) => {
25
+ }, g = async (e, t, n) => {
26
26
  let [i, a] = await Promise.all([e.downloadSkillFile(t, n, r), e.listSkillFiles({
27
27
  bucket: t,
28
28
  path: n,
29
29
  filePath: "",
30
30
  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");
31
+ })]), o = a.items.find((e) => e.nodeType === "item" && m(e, n) === "SKILL.md"), s = i.headers.get("etag") ?? o?.etag;
32
+ if (!s) throw new p("Skill ETag is missing");
33
33
  let c = a.items.filter((e) => e.nodeType === "item").map((e) => ({
34
34
  item: e,
35
- path: p(e, n)
35
+ path: m(e, n)
36
36
  })).filter((e) => e.path != null && e.path !== "SKILL.md"), l = await Promise.all(c.map(async ({ path: r }) => {
37
37
  let i = await e.downloadSkillFile(t, n, r);
38
38
  return [r, new Uint8Array(await i.arrayBuffer())];
@@ -42,40 +42,41 @@ var d = /* @__PURE__ */ function(e) {
42
42
  manifestText: await i.text(),
43
43
  files: new Map(l)
44
44
  };
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());
45
+ }, _ = ({ isEditMode: t, bucket: n, skillPath: r, client: o }) => {
46
+ let [d, m] = l(t ? "loading" : "loaded"), [_, v] = l(0), [y, b] = l(), x = c(void 0), S = c({}), C = c(void 0), [w, T] = l([]), E = c(/* @__PURE__ */ new Map());
47
47
  return s(() => {
48
48
  if (!t || !n) return;
49
49
  if (r == null) {
50
- p("error");
50
+ m("error");
51
51
  return;
52
52
  }
53
53
  let s = !1;
54
- return p("loading"), (async () => {
54
+ return m("loading"), (async () => {
55
55
  if (await Promise.resolve(), !s) try {
56
56
  let t;
57
57
  try {
58
- t = await m(o, n, r);
58
+ t = await h(o, n, r);
59
59
  } catch (i) {
60
+ if (i instanceof p) throw i;
60
61
  let a = e(i);
61
62
  if (!(i instanceof f) && a !== 400) throw i;
62
- t = await h(o, n, r);
63
+ t = await g(o, n, r);
63
64
  }
64
65
  let { frontmatter: c, instructions: l } = a(t.manifestText);
65
66
  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) => ({
67
+ x.current = t.etag, S.current = c, C.current = r, E.current = new Map([...t.files].map(([e, t]) => [e, { bytes: t }])), T([...t.files.keys()].map((e) => ({
67
68
  path: e,
68
69
  name: i(e),
69
70
  kind: u.File
70
- }))), y({
71
+ }))), b({
71
72
  name: typeof c.name == "string" ? c.name : "",
72
73
  description: typeof c.description == "string" ? c.description : "",
73
74
  instructions: l
74
- }), p("loaded");
75
+ }), m("loaded");
75
76
  } catch (t) {
76
77
  if (s) return;
77
78
  let n = e(t);
78
- p(n === 403 ? "forbidden" : n === 404 ? "not-found" : "error");
79
+ m(n === 403 ? "forbidden" : n === 404 ? "not-found" : "error");
79
80
  }
80
81
  })(), () => {
81
82
  s = !0;
@@ -84,20 +85,20 @@ var d = /* @__PURE__ */ function(e) {
84
85
  t,
85
86
  n,
86
87
  r,
87
- g,
88
+ _,
88
89
  o
89
90
  ]), {
90
91
  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)
92
+ loadedValues: y,
93
+ setLoadedValues: b,
94
+ files: w,
95
+ setFiles: T,
96
+ filesContentRef: E,
97
+ frontmatterRef: S,
98
+ etagRef: x,
99
+ loadedPathRef: C,
100
+ retryLoad: () => v((e) => e + 1)
100
101
  };
101
102
  };
102
103
  //#endregion
103
- export { d as SkillEditorLoadState, g as useSkillEditorLoad };
104
+ export { d as SkillEditorLoadState, _ as useSkillEditorLoad };