@epam/ai-dial-chat-hooks 1.2.0-dev.101 → 1.2.0-dev.106
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api-error/api-error.js +5 -4
- package/catalog/map-skill-to-catalog-item.js +52 -49
- package/index.d.ts +9 -4
- package/mcp-apps/useMcpAppTools/useMcpAppTools.js +1 -1
- package/package.json +16 -16
- package/scheduled-task/scheduled-task-trigger.js +7 -2
- package/scheduled-tasks.d.ts +2 -3
- package/skill/useSkillEditorLoad.js +29 -28
- package/skill/useSkillEditorSubmit.js +42 -37
- package/skill-editor.d.ts +4 -0
- package/utils.d.ts +3 -1
package/api-error/api-error.js
CHANGED
|
@@ -26,19 +26,20 @@ var e = (e) => typeof e == "object" && !!e, t = (t) => {
|
|
|
26
26
|
}
|
|
27
27
|
return e instanceof Error && e.message ? e.message : null;
|
|
28
28
|
}, d = async (t) => {
|
|
29
|
-
let r = s(t), i = r?.status, a = null, c, l = !1;
|
|
29
|
+
let r = s(t), i = r?.status, a = null, c, l = !1, u;
|
|
30
30
|
if (r) try {
|
|
31
31
|
let t = await (typeof r.clone == "function" ? r.clone() : r).json();
|
|
32
|
-
a = n(t), e(t) && (c = o(t.traceparent));
|
|
32
|
+
a = n(t), e(t) && (u = typeof t.code == "string" ? t.code : void 0, c = o(t.traceparent));
|
|
33
33
|
} catch {
|
|
34
34
|
l = !0;
|
|
35
35
|
}
|
|
36
36
|
!l && a === null && t instanceof Error && t.message && (a = t.message);
|
|
37
|
-
let
|
|
37
|
+
let d = c ?? o(typeof r?.headers?.get == "function" ? r.headers.get("traceparent") : void 0);
|
|
38
38
|
return {
|
|
39
39
|
status: i,
|
|
40
40
|
message: a,
|
|
41
|
-
traceId:
|
|
41
|
+
traceId: d,
|
|
42
|
+
...u ? { code: u } : {}
|
|
42
43
|
};
|
|
43
44
|
};
|
|
44
45
|
//#endregion
|
|
@@ -1,24 +1,27 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { formatCalendarDate as
|
|
1
|
+
import { safeDecodeURIComponent as e, stripSurroundingSlashes as t } from "../shared/string-utils.js";
|
|
2
|
+
import { formatCalendarDate as n } from "../shared/formatting.js";
|
|
3
3
|
import "../skill/skill.js";
|
|
4
|
-
import { SkillSource as
|
|
5
|
-
import { CatalogEntityType as
|
|
6
|
-
import { CatalogContentNodeType as
|
|
7
|
-
import { SkillMetadataItemDtoNodeTypeEnum as
|
|
4
|
+
import { SkillSource as r } from "../skill/skill-types.js";
|
|
5
|
+
import { CatalogEntityType as i, formatLastUsed as a } from "@epam/ai-dial-chat-shared";
|
|
6
|
+
import { CatalogContentNodeType as o } from "@epam/ai-dial-catalog";
|
|
7
|
+
import { SkillMetadataItemDtoNodeTypeEnum as s } from "@epam/ai-dial-chat-api-client";
|
|
8
8
|
//#region src/catalog/map-skill-to-catalog-item.ts
|
|
9
|
-
var
|
|
10
|
-
[
|
|
11
|
-
[
|
|
12
|
-
[
|
|
13
|
-
},
|
|
14
|
-
let
|
|
9
|
+
var c = {
|
|
10
|
+
[r.Personal]: "personal",
|
|
11
|
+
[r.SharedWithMe]: "shared",
|
|
12
|
+
[r.Public]: "public"
|
|
13
|
+
}, l = (t, n) => {
|
|
14
|
+
let r = (n ?? "").split("/").filter(Boolean), i = t.split("/").filter(Boolean).slice(2, -1);
|
|
15
|
+
return i.length === r.length ? i.map(e) : r;
|
|
16
|
+
}, u = (e, t, n) => [n[c[t]], ...l(e.url, e.parentPath)], d = (e, { folderLabels: t, source: n, favoriteIds: o }) => {
|
|
17
|
+
let s = o.has(e.url), c = n === r.Public, l = n === r.Personal;
|
|
15
18
|
return {
|
|
16
19
|
id: e.url,
|
|
17
|
-
type:
|
|
20
|
+
type: i.Skill,
|
|
18
21
|
name: e.name,
|
|
19
22
|
description: e.description ?? "",
|
|
20
23
|
version: "",
|
|
21
|
-
lastUsed:
|
|
24
|
+
lastUsed: a(e.updatedAt),
|
|
22
25
|
createdAt: e.createdAt,
|
|
23
26
|
updatedAt: e.updatedAt,
|
|
24
27
|
isFeatured: !1,
|
|
@@ -26,12 +29,12 @@ var s = {
|
|
|
26
29
|
topics: [],
|
|
27
30
|
isUserFavorite: s,
|
|
28
31
|
isStarred: s,
|
|
29
|
-
isMyApp:
|
|
30
|
-
sharedWithMe: e.sharedWithMe ??
|
|
31
|
-
isEditable: !
|
|
32
|
-
folder:
|
|
32
|
+
isMyApp: l && (e.isMy ?? !0),
|
|
33
|
+
sharedWithMe: e.sharedWithMe ?? n === r.SharedWithMe,
|
|
34
|
+
isEditable: !c && (e.canEdit ?? l),
|
|
35
|
+
folder: u(e, n, t)
|
|
33
36
|
};
|
|
34
|
-
},
|
|
37
|
+
}, f = (e) => e.join(" · "), p = (e, t) => {
|
|
35
38
|
if (e == null) return null;
|
|
36
39
|
let n = [];
|
|
37
40
|
return e.whenToUse != null && n.push({
|
|
@@ -39,25 +42,25 @@ var s = {
|
|
|
39
42
|
value: e.whenToUse
|
|
40
43
|
}), e.allowedTools?.length && n.push({
|
|
41
44
|
label: t.allowedToolsLabel,
|
|
42
|
-
value:
|
|
45
|
+
value: f(e.allowedTools)
|
|
43
46
|
}), e.bundledResources?.length && n.push({
|
|
44
47
|
label: t.bundledResourcesLabel,
|
|
45
|
-
value:
|
|
48
|
+
value: f(e.bundledResources)
|
|
46
49
|
}), n.length === 0 ? null : {
|
|
47
50
|
title: t.specificationSectionTitle,
|
|
48
51
|
specs: n
|
|
49
52
|
};
|
|
50
|
-
},
|
|
51
|
-
let r =
|
|
52
|
-
return
|
|
53
|
-
let n = e
|
|
53
|
+
}, m = (e) => e.filter((e) => e.nodeType === s.Item), h = (e, n) => {
|
|
54
|
+
let r = t(n), i = r ? `${r}/files` : "files";
|
|
55
|
+
return m(e).find((e) => {
|
|
56
|
+
let n = t(e.path);
|
|
54
57
|
return n === "SKILL.md" || n === "files/SKILL.md" || n === `${i}/SKILL.md`;
|
|
55
58
|
})?.path ?? "SKILL.md";
|
|
56
|
-
},
|
|
57
|
-
let r = e
|
|
59
|
+
}, g = (e, n) => {
|
|
60
|
+
let r = t(e), i = t(n), a = i ? `${i}/files` : "files";
|
|
58
61
|
return r === "" || r === "files" || r === a ? null : r.startsWith(`${a}/`) ? r.slice(a.length + 1) : r.startsWith("files/") ? r.slice(6) : r;
|
|
59
|
-
},
|
|
60
|
-
let a = [], o =
|
|
62
|
+
}, _ = (e, t) => g(e, t), v = (e, t, r, i) => {
|
|
63
|
+
let a = [], o = p(r, i);
|
|
61
64
|
o != null && a.push(o);
|
|
62
65
|
let s = [];
|
|
63
66
|
return e?.author && s.push({
|
|
@@ -65,26 +68,26 @@ var s = {
|
|
|
65
68
|
value: e.author
|
|
66
69
|
}), s.push({
|
|
67
70
|
label: i.updatedLabel,
|
|
68
|
-
value: e?.updatedAt ?
|
|
71
|
+
value: e?.updatedAt ? n(e.updatedAt) : ""
|
|
69
72
|
}), s.push({
|
|
70
73
|
label: i.fileCountLabel,
|
|
71
|
-
value: String(
|
|
74
|
+
value: String(m(t).length)
|
|
72
75
|
}), a.push({
|
|
73
76
|
title: i.detailsSectionTitle,
|
|
74
77
|
specs: s
|
|
75
78
|
}), { sections: a };
|
|
76
|
-
},
|
|
79
|
+
}, y = (e, t, n) => {
|
|
77
80
|
if (e === "") return n;
|
|
78
81
|
let r = t.get(e);
|
|
79
82
|
if (r != null) return r.items;
|
|
80
|
-
let i = e.split("/"),
|
|
81
|
-
type:
|
|
83
|
+
let i = e.split("/"), a = y(i.slice(0, -1).join("/"), t, n), s = {
|
|
84
|
+
type: o.Folder,
|
|
82
85
|
id: e,
|
|
83
86
|
name: i[i.length - 1],
|
|
84
87
|
items: []
|
|
85
88
|
};
|
|
86
|
-
return t.set(e, s),
|
|
87
|
-
},
|
|
89
|
+
return t.set(e, s), a.push(s), s.items;
|
|
90
|
+
}, b = (e, t) => {
|
|
88
91
|
e.sort((e, n) => {
|
|
89
92
|
if (t) {
|
|
90
93
|
if (e.name === "SKILL.md") return -1;
|
|
@@ -92,32 +95,32 @@ var s = {
|
|
|
92
95
|
}
|
|
93
96
|
return e.name.localeCompare(n.name);
|
|
94
97
|
});
|
|
95
|
-
for (let t of e) t.type ===
|
|
96
|
-
},
|
|
98
|
+
for (let t of e) t.type === o.Folder && b(t.items, !1);
|
|
99
|
+
}, x = (e, t) => {
|
|
97
100
|
let n = /* @__PURE__ */ new Map(), r = [];
|
|
98
101
|
for (let i of e) {
|
|
99
|
-
let e =
|
|
102
|
+
let e = g(i.path, t);
|
|
100
103
|
if (e == null) continue;
|
|
101
|
-
if (i.nodeType ===
|
|
102
|
-
|
|
104
|
+
if (i.nodeType === s.Folder) {
|
|
105
|
+
y(e, n, r);
|
|
103
106
|
continue;
|
|
104
107
|
}
|
|
105
|
-
let
|
|
106
|
-
|
|
107
|
-
type:
|
|
108
|
+
let a = e.lastIndexOf("/");
|
|
109
|
+
y(a === -1 ? "" : e.slice(0, a), n, r).push({
|
|
110
|
+
type: o.File,
|
|
108
111
|
id: i.path,
|
|
109
112
|
name: i.name
|
|
110
113
|
});
|
|
111
114
|
}
|
|
112
|
-
return
|
|
113
|
-
},
|
|
115
|
+
return b(r, !0), r;
|
|
116
|
+
}, S = async (e) => {
|
|
114
117
|
let t = Number(e.headers.get("content-length"));
|
|
115
118
|
if (Number.isFinite(t) && t > 262144) return null;
|
|
116
119
|
let n = await e.arrayBuffer();
|
|
117
120
|
return n.byteLength > 262144 ? null : new Uint8Array(n);
|
|
118
|
-
},
|
|
119
|
-
let t = await
|
|
121
|
+
}, C = async (e) => new Uint8Array(await e.arrayBuffer()), w = async (e) => {
|
|
122
|
+
let t = await S(e);
|
|
120
123
|
return t == null ? null : new TextDecoder().decode(t);
|
|
121
124
|
};
|
|
122
125
|
//#endregion
|
|
123
|
-
export {
|
|
126
|
+
export { x as buildSkillContentTree, v as buildSkillOverview, d as mapSkillToCatalogItem, S as readSkillFileBytes, C as readSkillFilePreviewBytes, w as readSkillManifest, _ as resolveSkillFileDownloadPath, h as resolveSkillManifestFileId };
|
package/index.d.ts
CHANGED
|
@@ -256,6 +256,8 @@ export declare interface AnnouncementListItemLink {
|
|
|
256
256
|
|
|
257
257
|
/** Normalized shape returned by {@link getApiErrorDetails}. */
|
|
258
258
|
export declare interface ApiErrorDetails {
|
|
259
|
+
/** Stable domain error code supplied by the API, when present. */
|
|
260
|
+
code?: string;
|
|
259
261
|
/** HTTP status code carried by the error, when available. */
|
|
260
262
|
status?: number;
|
|
261
263
|
/** Resolved human-readable error message, or `null` when none could be resolved. */
|
|
@@ -1721,7 +1723,7 @@ export declare class GenerationConflictError extends Error {
|
|
|
1721
1723
|
constructor(message?: string);
|
|
1722
1724
|
}
|
|
1723
1725
|
|
|
1724
|
-
/** Normalizes any API error into a `{ status?, message, traceId? }` shape. */
|
|
1726
|
+
/** Normalizes any API error into a `{ status?, message, traceId?, code? }` shape. */
|
|
1725
1727
|
export declare const getApiErrorDetails: (error: unknown) => Promise<ApiErrorDetails>;
|
|
1726
1728
|
|
|
1727
1729
|
/** Resolves a human-readable message from an API error's response body, or falls back to `Error.message`. */
|
|
@@ -2209,9 +2211,8 @@ export declare const mapFileMetadataToDialFile: (metadata: FileMetadataResponseD
|
|
|
2209
2211
|
export declare const mapFormValuesToCreateBody: (values: ScheduledTaskCreateFormValues) => CreateScheduledTaskBodyDto;
|
|
2210
2212
|
|
|
2211
2213
|
/**
|
|
2212
|
-
* Maps validated edit
|
|
2213
|
-
*
|
|
2214
|
-
* `CreateScheduledTaskBodyDto`, so this reuses the same trigger-building logic.
|
|
2214
|
+
* Maps a complete, validated edit draft to an update body. An unset skill
|
|
2215
|
+
* emits null to remove the saved reference; hydrate from detail before editing.
|
|
2215
2216
|
*/
|
|
2216
2217
|
export declare const mapFormValuesToUpdateBody: (values: ScheduledTaskCreateFormValues) => UpdateScheduledTaskBodyDto;
|
|
2217
2218
|
|
|
@@ -6079,6 +6080,10 @@ export declare interface UseSkillEditorSubmitResult {
|
|
|
6079
6080
|
errors: SkillEditorErrors;
|
|
6080
6081
|
/** General submit-time error, distinct from a stale-edit `conflict`. */
|
|
6081
6082
|
submitError: string | undefined;
|
|
6083
|
+
/** Whether `submitError` was caused by something a plain re-send can clear, rather than by the submission itself. */
|
|
6084
|
+
isSubmitErrorRetryable: boolean;
|
|
6085
|
+
/** Re-submits the values of the attempt that produced `submitError`. No-op before the first submit. */
|
|
6086
|
+
retrySubmit: () => void;
|
|
6082
6087
|
/** Present when the last save hit a stale-ETag conflict. */
|
|
6083
6088
|
conflict: {
|
|
6084
6089
|
message: string;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@epam/ai-dial-chat-hooks",
|
|
3
3
|
"description": "Framework-level React hooks extracted from AI DIAL Chat for building custom chat interfaces",
|
|
4
|
-
"version": "1.2.0-dev.
|
|
4
|
+
"version": "1.2.0-dev.106",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./index.js",
|
|
@@ -111,7 +111,7 @@
|
|
|
111
111
|
}
|
|
112
112
|
},
|
|
113
113
|
"dependencies": {
|
|
114
|
-
"@epam/ai-dial-chat-api-client": "1.2.0-dev.
|
|
114
|
+
"@epam/ai-dial-chat-api-client": "1.2.0-dev.106",
|
|
115
115
|
"dompurify": "3.4.15",
|
|
116
116
|
"fflate": "^0.8.3",
|
|
117
117
|
"lru-cache": "^10.4.3",
|
|
@@ -120,22 +120,22 @@
|
|
|
120
120
|
},
|
|
121
121
|
"peerDependencies": {
|
|
122
122
|
"react": "^19.2.8",
|
|
123
|
-
"@epam/ai-dial-attachment-canvas": "1.2.0-dev.
|
|
124
|
-
"@epam/ai-dial-attachment-input": "1.2.0-dev.
|
|
125
|
-
"@epam/ai-dial-builder-form": "1.2.0-dev.
|
|
126
|
-
"@epam/ai-dial-catalog": "1.2.0-dev.
|
|
127
|
-
"@epam/ai-dial-chat-overlay": "1.2.0-dev.
|
|
128
|
-
"@epam/ai-dial-chat-shared": "1.2.0-dev.
|
|
129
|
-
"@epam/ai-dial-mcp-apps": "1.2.0-dev.
|
|
130
|
-
"@epam/ai-dial-publish-panel": "1.2.0-dev.
|
|
131
|
-
"@epam/ai-dial-quotations": "1.2.0-dev.
|
|
123
|
+
"@epam/ai-dial-attachment-canvas": "1.2.0-dev.106",
|
|
124
|
+
"@epam/ai-dial-attachment-input": "1.2.0-dev.106",
|
|
125
|
+
"@epam/ai-dial-builder-form": "1.2.0-dev.106",
|
|
126
|
+
"@epam/ai-dial-catalog": "1.2.0-dev.106",
|
|
127
|
+
"@epam/ai-dial-chat-overlay": "1.2.0-dev.106",
|
|
128
|
+
"@epam/ai-dial-chat-shared": "1.2.0-dev.106",
|
|
129
|
+
"@epam/ai-dial-mcp-apps": "1.2.0-dev.106",
|
|
130
|
+
"@epam/ai-dial-publish-panel": "1.2.0-dev.106",
|
|
131
|
+
"@epam/ai-dial-quotations": "1.2.0-dev.106",
|
|
132
132
|
"@epam/ai-dial-react-file-manager": "^0.3.0-dev.4",
|
|
133
|
-
"@epam/ai-dial-scheduled-tasks": "1.2.0-dev.
|
|
134
|
-
"@epam/ai-dial-share": "1.2.0-dev.
|
|
135
|
-
"@epam/ai-dial-skill-editor": "1.2.0-dev.
|
|
136
|
-
"@epam/ai-dial-source-panel": "1.2.0-dev.
|
|
133
|
+
"@epam/ai-dial-scheduled-tasks": "1.2.0-dev.106",
|
|
134
|
+
"@epam/ai-dial-share": "1.2.0-dev.106",
|
|
135
|
+
"@epam/ai-dial-skill-editor": "1.2.0-dev.106",
|
|
136
|
+
"@epam/ai-dial-source-panel": "1.2.0-dev.106",
|
|
137
137
|
"@epam/ai-dial-ui-kit": "^0.15.0-dev.12",
|
|
138
|
-
"@epam/ai-dial-usage-dashboard": "1.2.0-dev.
|
|
138
|
+
"@epam/ai-dial-usage-dashboard": "1.2.0-dev.106",
|
|
139
139
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
140
140
|
"@epam/pdf-highlighter-kit": "^0.0.19",
|
|
141
141
|
"@mcp-ui/client": "^7.1.1"
|
|
@@ -42,9 +42,13 @@ var a = new Set([
|
|
|
42
42
|
trigger: t,
|
|
43
43
|
model: e.modelId,
|
|
44
44
|
prompt: e.prompt.trim(),
|
|
45
|
+
...e.skillUrl ? { skillUrl: e.skillUrl } : {},
|
|
45
46
|
...n ? { description: n } : {}
|
|
46
47
|
};
|
|
47
|
-
}, u = (e) =>
|
|
48
|
+
}, u = (e) => ({
|
|
49
|
+
...l(e),
|
|
50
|
+
skillUrl: e.skillUrl || null
|
|
51
|
+
}), d = (t) => {
|
|
48
52
|
let n = new Date(t);
|
|
49
53
|
return `${n.getFullYear()}-${e(n.getMonth() + 1)}-${e(n.getDate())}T${e(n.getHours())}:${e(n.getMinutes())}`;
|
|
50
54
|
}, f = (t) => {
|
|
@@ -82,7 +86,7 @@ var a = new Set([
|
|
|
82
86
|
...c ? { dayOfMonth: String(d.getDate()) } : {}
|
|
83
87
|
};
|
|
84
88
|
}, m = (e) => {
|
|
85
|
-
if (!e.model || !e.prompt) return {
|
|
89
|
+
if (!e.model || typeof e.prompt != "string" || !e.prompt.trim() && !e.skillUrl) return {
|
|
86
90
|
ok: !1,
|
|
87
91
|
reason: t.MissingRequiredFields
|
|
88
92
|
};
|
|
@@ -95,6 +99,7 @@ var a = new Set([
|
|
|
95
99
|
displayName: e.displayName,
|
|
96
100
|
modelId: e.model,
|
|
97
101
|
prompt: e.prompt,
|
|
102
|
+
...e.skillUrl ? { skillUrl: e.skillUrl } : {},
|
|
98
103
|
...e.description ? { description: e.description } : {}
|
|
99
104
|
};
|
|
100
105
|
if (a) return {
|
package/scheduled-tasks.d.ts
CHANGED
|
@@ -38,9 +38,8 @@ export declare const describeScheduledTaskTrigger: (trigger: ScheduleTriggerDto,
|
|
|
38
38
|
export declare const mapFormValuesToCreateBody: (values: ScheduledTaskCreateFormValues) => CreateScheduledTaskBodyDto;
|
|
39
39
|
|
|
40
40
|
/**
|
|
41
|
-
* Maps validated edit
|
|
42
|
-
*
|
|
43
|
-
* `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.
|
|
44
43
|
*/
|
|
45
44
|
export declare const mapFormValuesToUpdateBody: (values: ScheduledTaskCreateFormValues) => UpdateScheduledTaskBodyDto;
|
|
46
45
|
|
|
@@ -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
|
-
},
|
|
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
|
|
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
|
-
},
|
|
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" &&
|
|
32
|
-
if (!s) throw
|
|
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:
|
|
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
|
-
},
|
|
46
|
-
let [d,
|
|
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
|
-
|
|
50
|
+
m("error");
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
53
|
let s = !1;
|
|
54
|
-
return
|
|
54
|
+
return m("loading"), (async () => {
|
|
55
55
|
if (await Promise.resolve(), !s) try {
|
|
56
56
|
let t;
|
|
57
57
|
try {
|
|
58
|
-
t = await
|
|
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
|
|
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
|
-
|
|
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
|
-
}))),
|
|
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
|
-
}),
|
|
75
|
+
}), m("loaded");
|
|
75
76
|
} catch (t) {
|
|
76
77
|
if (s) return;
|
|
77
78
|
let n = e(t);
|
|
78
|
-
|
|
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
|
-
|
|
88
|
+
_,
|
|
88
89
|
o
|
|
89
90
|
]), {
|
|
90
91
|
loadState: d,
|
|
91
|
-
loadedValues:
|
|
92
|
-
setLoadedValues:
|
|
93
|
-
files:
|
|
94
|
-
setFiles:
|
|
95
|
-
filesContentRef:
|
|
96
|
-
frontmatterRef:
|
|
97
|
-
etagRef:
|
|
98
|
-
loadedPathRef:
|
|
99
|
-
retryLoad: () =>
|
|
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,
|
|
104
|
+
export { d as SkillEditorLoadState, _ as useSkillEditorLoad };
|
|
@@ -7,7 +7,7 @@ var d = (e, t) => JSON.stringify({
|
|
|
7
7
|
values: e,
|
|
8
8
|
files: [...t].sort((e, t) => e.path.localeCompare(t.path))
|
|
9
9
|
}), f = ({ bucket: f, isEditMode: p, files: m, filesContentRef: h, frontmatterRef: g, loadedPathRef: _, etagRef: v, returnUrl: y, refetchSkills: b, client: x, messages: S, onNavigate: C, onNotify: w }) => {
|
|
10
|
-
let [T, E] = l({}), [D, O] = l(), [k, A] = l(), [j, M] = l("idle"),
|
|
10
|
+
let [T, E] = l({}), [D, O] = l(), [k, A] = l(!1), [j, M] = l(), [N, P] = l("idle"), F = c(null), I = c(null), L = s(async (n) => {
|
|
11
11
|
switch (t(n)) {
|
|
12
12
|
case 409:
|
|
13
13
|
E({ name: S.nameConflict });
|
|
@@ -19,7 +19,7 @@ var d = (e, t) => JSON.stringify({
|
|
|
19
19
|
O(S.archiveTooLarge);
|
|
20
20
|
return;
|
|
21
21
|
case 503:
|
|
22
|
-
O(S.serviceUnavailable);
|
|
22
|
+
O(S.serviceUnavailable), A(!0);
|
|
23
23
|
return;
|
|
24
24
|
case 400: {
|
|
25
25
|
let { message: t } = await e(n);
|
|
@@ -35,14 +35,14 @@ var d = (e, t) => JSON.stringify({
|
|
|
35
35
|
});
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
-
}, [S, w]),
|
|
38
|
+
}, [S, w]), R = s(async (e) => {
|
|
39
39
|
let t = a(e.name);
|
|
40
40
|
if (!t || !i(t)) {
|
|
41
41
|
E({ name: S.nameInvalid });
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
44
|
-
let o = d(e, m), s =
|
|
45
|
-
c ? {skillManifest: p, filePaths: _, files: v} = s : (p = r(g.current, t, e.description, e.instructions), {filePaths: _, files: v} = n(m, h.current)),
|
|
44
|
+
let o = d(e, m), s = F.current, c = s != null && s.fingerprint === o, l = t, p, _, v;
|
|
45
|
+
c ? {skillManifest: p, filePaths: _, files: v} = s : (p = r(g.current, t, e.description, e.instructions), {filePaths: _, files: v} = n(m, h.current)), P("submitting"), F.current = {
|
|
46
46
|
fingerprint: o,
|
|
47
47
|
bucket: f,
|
|
48
48
|
path: l,
|
|
@@ -51,13 +51,13 @@ var d = (e, t) => JSON.stringify({
|
|
|
51
51
|
files: v
|
|
52
52
|
};
|
|
53
53
|
try {
|
|
54
|
-
await x.createSkill(f, l, p, _, v), await b(),
|
|
54
|
+
await x.createSkill(f, l, p, _, v), await b(), P("success"), w({
|
|
55
55
|
variant: u.Success,
|
|
56
56
|
title: S.saveSuccessTitle,
|
|
57
57
|
message: S.createSuccess(t)
|
|
58
58
|
}), C(y);
|
|
59
59
|
} catch (e) {
|
|
60
|
-
|
|
60
|
+
P("failure"), await L(e);
|
|
61
61
|
}
|
|
62
62
|
}, [
|
|
63
63
|
f,
|
|
@@ -70,27 +70,27 @@ var d = (e, t) => JSON.stringify({
|
|
|
70
70
|
C,
|
|
71
71
|
y,
|
|
72
72
|
b,
|
|
73
|
-
|
|
74
|
-
]),
|
|
73
|
+
L
|
|
74
|
+
]), z = s(async (e) => {
|
|
75
75
|
let i = _.current, a = v.current;
|
|
76
76
|
if (!i || !a) {
|
|
77
77
|
O(S.saveError);
|
|
78
78
|
return;
|
|
79
79
|
}
|
|
80
80
|
let o = r(g.current, e.name, e.description, e.instructions), { filePaths: s, files: c } = n(m, h.current);
|
|
81
|
-
|
|
81
|
+
P("submitting");
|
|
82
82
|
try {
|
|
83
|
-
v.current = (await x.updateSkill(f, i, o, s, c, a)).etag ?? a, await b(),
|
|
83
|
+
v.current = (await x.updateSkill(f, i, o, s, c, a)).etag ?? a, await b(), P("success"), w({
|
|
84
84
|
variant: u.Success,
|
|
85
85
|
title: S.updateSuccessTitle,
|
|
86
86
|
message: S.updateSuccess(e.name)
|
|
87
87
|
}), C(y);
|
|
88
88
|
} catch (e) {
|
|
89
|
-
if (
|
|
90
|
-
|
|
89
|
+
if (P("failure"), t(e) === 412) {
|
|
90
|
+
M({ message: S.conflictMessage });
|
|
91
91
|
return;
|
|
92
92
|
}
|
|
93
|
-
await
|
|
93
|
+
await L(e);
|
|
94
94
|
}
|
|
95
95
|
}, [
|
|
96
96
|
f,
|
|
@@ -105,8 +105,8 @@ var d = (e, t) => JSON.stringify({
|
|
|
105
105
|
C,
|
|
106
106
|
y,
|
|
107
107
|
b,
|
|
108
|
-
|
|
109
|
-
]),
|
|
108
|
+
L
|
|
109
|
+
]), B = s((e) => {
|
|
110
110
|
let t = o(e.instructions);
|
|
111
111
|
E((e) => {
|
|
112
112
|
if (t === (e.instructions === S.instructionsFrontmatter)) return e;
|
|
@@ -117,30 +117,35 @@ var d = (e, t) => JSON.stringify({
|
|
|
117
117
|
let n = { ...e };
|
|
118
118
|
return delete n.instructions, n;
|
|
119
119
|
});
|
|
120
|
-
}, [S])
|
|
120
|
+
}, [S]), V = s(async (e) => {
|
|
121
|
+
if (N === "submitting" || !f) return;
|
|
122
|
+
let t = {};
|
|
123
|
+
if (e.name.trim() || (t.name = S.required), e.description.trim() || (t.description = S.required), e.instructions.trim() ? o(e.instructions) && (t.instructions = S.instructionsFrontmatter) : t.instructions = S.required, Object.keys(t).length > 0) {
|
|
124
|
+
E(t);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
E({}), O(void 0), A(!1), M(void 0), I.current = e, p ? await z(e) : await R(e);
|
|
128
|
+
}, [
|
|
129
|
+
N,
|
|
130
|
+
f,
|
|
131
|
+
S,
|
|
132
|
+
p,
|
|
133
|
+
z,
|
|
134
|
+
R
|
|
135
|
+
]);
|
|
121
136
|
return {
|
|
122
|
-
phase:
|
|
137
|
+
phase: N,
|
|
123
138
|
errors: T,
|
|
124
139
|
submitError: D,
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
E({}), O(void 0), A(void 0), p ? await I(e) : await F(e);
|
|
135
|
-
}, [
|
|
136
|
-
j,
|
|
137
|
-
f,
|
|
138
|
-
S,
|
|
139
|
-
p,
|
|
140
|
-
I,
|
|
141
|
-
F
|
|
142
|
-
]),
|
|
143
|
-
handleValuesChange: L
|
|
140
|
+
isSubmitErrorRetryable: k,
|
|
141
|
+
retrySubmit: s(() => {
|
|
142
|
+
let e = I.current;
|
|
143
|
+
e != null && V(e);
|
|
144
|
+
}, [V]),
|
|
145
|
+
conflict: j,
|
|
146
|
+
clearConflict: () => M(void 0),
|
|
147
|
+
handleSubmit: V,
|
|
148
|
+
handleValuesChange: B
|
|
144
149
|
};
|
|
145
150
|
};
|
|
146
151
|
//#endregion
|
package/skill-editor.d.ts
CHANGED
|
@@ -534,6 +534,10 @@ export declare interface UseSkillEditorSubmitResult {
|
|
|
534
534
|
errors: SkillEditorErrors;
|
|
535
535
|
/** General submit-time error, distinct from a stale-edit `conflict`. */
|
|
536
536
|
submitError: string | undefined;
|
|
537
|
+
/** Whether `submitError` was caused by something a plain re-send can clear, rather than by the submission itself. */
|
|
538
|
+
isSubmitErrorRetryable: boolean;
|
|
539
|
+
/** Re-submits the values of the attempt that produced `submitError`. No-op before the first submit. */
|
|
540
|
+
retrySubmit: () => void;
|
|
537
541
|
/** Present when the last save hit a stale-ETag conflict. */
|
|
538
542
|
conflict: {
|
|
539
543
|
message: string;
|
package/utils.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ import { UserLimitStatsResponseDto } from '@epam/ai-dial-chat-api-client';
|
|
|
10
10
|
|
|
11
11
|
/** Normalized shape returned by {@link getApiErrorDetails}. */
|
|
12
12
|
export declare interface ApiErrorDetails {
|
|
13
|
+
/** Stable domain error code supplied by the API, when present. */
|
|
14
|
+
code?: string;
|
|
13
15
|
/** HTTP status code carried by the error, when available. */
|
|
14
16
|
status?: number;
|
|
15
17
|
/** Resolved human-readable error message, or `null` when none could be resolved. */
|
|
@@ -132,7 +134,7 @@ export declare interface ExportedPrompt {
|
|
|
132
134
|
/** Formats a Unix timestamp (ms) as a locale-formatted calendar date, e.g. `'22/7/2026'`. */
|
|
133
135
|
export declare const formatCalendarDate: (timestampMs: number) => string;
|
|
134
136
|
|
|
135
|
-
/** Normalizes any API error into a `{ status?, message, traceId? }` shape. */
|
|
137
|
+
/** Normalizes any API error into a `{ status?, message, traceId?, code? }` shape. */
|
|
136
138
|
export declare const getApiErrorDetails: (error: unknown) => Promise<ApiErrorDetails>;
|
|
137
139
|
|
|
138
140
|
/** Resolves a human-readable message from an API error's response body, or falls back to `Error.message`. */
|