@epam/ai-dial-chat-hooks 1.2.0-dev.21 → 1.2.0-dev.213
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/attachment/useAttachmentValidation/useAttachmentValidation.js +26 -19
- package/attachments.d.ts +10 -4
- package/catalog/catalog-derivations.js +1 -1
- package/catalog/deployment-id.js +8 -2
- package/catalog/map-deployment-limits-to-input.js +81 -9
- package/catalog/map-deployment-to-catalog-item.js +34 -34
- package/catalog/map-entity-details-to-catalog.js +7 -0
- package/catalog/map-skill-to-catalog-item.js +30 -27
- package/catalog/publish.js +6 -5
- package/catalog/useApplicationCredentials/useApplicationCredentials.js +39 -0
- package/catalog/useSkillDetailsPanelData/useSkillDetailsPanelData.js +39 -39
- package/catalog/useSkillItemDetails.js +17 -13
- package/catalog.d.ts +116 -20
- package/catalog.js +23 -22
- package/conversation/conversation-transfer/export-conversation.js +24 -16
- package/conversation/conversation-transfer/import-conversation.js +80 -31
- package/conversation/conversation-transfer/queue.js +8 -5
- package/conversation/create-chat-stream-api.js +85 -49
- package/conversation/message-utils.js +44 -2
- package/conversation/stage.js +23 -0
- package/conversation/useConversationExport/useConversationExport.js +9 -9
- package/conversation/useConversationHandlers/useConversationHandlers.js +16 -5
- package/conversation/useConversationImport/useConversationImport.js +123 -121
- package/conversation/useConversationPanelItems/useConversationPanelItems.js +2 -3
- package/conversation/useConversationScroll/useConversationScroll.js +68 -64
- package/conversation/useConversationStream/apply-chunk.js +1 -1
- package/conversation/useConversationStream/generation-resume.js +104 -63
- package/conversation/useConversationStream/useConversationStream.js +181 -110
- package/conversation/useMessageSelectionReply/useMessageSelectionReply.js +189 -0
- package/conversation-overlay.d.ts +7 -0
- package/conversation-overlay.js +2 -0
- package/conversation-sources/useConversationSources/useConversationSources.js +31 -24
- package/conversation-sources.d.ts +1 -1
- package/conversation-transfer.d.ts +2 -1
- package/conversation.d.ts +241 -13
- package/conversation.js +32 -30
- package/file-manager-canvas.d.ts +398 -0
- package/file-manager-canvas.js +2 -0
- package/file-manager.d.ts +153 -350
- package/file-manager.js +25 -24
- package/files/attachment-canvas.js +40 -1
- package/files/attachment-types.js +14 -13
- package/files/dial-file-manager-mapping.util.js +2 -1
- package/files/dial-file-manager-path.util.js +23 -1
- package/files/dial-file-manager.model.js +23 -19
- package/files/dial-file-manager.types.js +3 -3
- package/files/useDialFileListing/useDialFileListing.js +157 -145
- package/files/useDialFileManager/useDialFileManager.js +132 -128
- package/files/useDialFileManagerSections/useDialFileManagerSections.js +155 -0
- package/files/useDialFileManagerTabConfig/useDialFileManagerTabConfig.js +20 -19
- package/files/useDialFileMutations/useDialFileMutations.js +33 -32
- package/files/useDialFileUploadBatch/useDialFileUploadBatch.js +117 -110
- package/files/useFileAttachmentPicker/useFileAttachmentPicker.js +43 -0
- package/index.d.ts +1068 -81
- package/index.js +136 -122
- package/mcp-apps/useMcpAppHostAdapter/useMcpAppHostAdapter.js +7 -5
- package/mcp-apps/useMcpAppHostContext/useMcpAppHostContext.js +1 -1
- package/mcp-apps/useMcpAppTools/useMcpAppTools.js +1 -1
- package/mcp-apps/useOpenMcpAppCanvas/useOpenMcpAppCanvas.js +25 -23
- package/mcp-apps.d.ts +8 -6
- package/oauth/toolset-id.js +5 -3
- package/oauth/useToolsetLogin/useToolsetLogin.js +8 -8
- package/oauth.d.ts +32 -0
- package/oauth.js +9 -9
- package/package.json +36 -21
- package/scheduled-task/scheduled-task-description.js +77 -0
- package/scheduled-task/scheduled-task-preparation.js +24 -0
- package/scheduled-task/scheduled-task-trigger.js +7 -2
- package/scheduled-task/scheduled-tasks-api-client.js +19 -0
- package/scheduled-task/use-scheduled-task-runs.js +194 -0
- package/scheduled-task/use-scheduled-tasks.js +93 -0
- package/scheduled-tasks.d.ts +195 -3
- package/scheduled-tasks.js +7 -2
- package/skill/skill-archive.js +19 -0
- package/skill/skill-types.js +8 -7
- package/skill/skill.js +42 -27
- package/skill/useSkillArchiveImport/useSkillArchiveImport.js +79 -0
- package/skill/useSkillEditorLoad.js +29 -28
- package/skill/useSkillEditorSubmit.js +108 -84
- package/skill/useSkillFileActions.js +70 -58
- package/skill-editor.d.ts +133 -3
- package/skill-editor.js +9 -8
- package/usage/map-usage-data-to-dashboard.js +66 -0
- package/usage/map-user-usage-to-model-limits.js +202 -0
- package/usage.d.ts +125 -0
- package/usage.js +3 -0
- package/usePageFileDrag/usePageFileDrag.js +3 -3
- package/utils.d.ts +8 -6
|
@@ -1,135 +1,159 @@
|
|
|
1
1
|
import { getApiErrorDetails as e, getApiErrorStatus as t } from "../api-error/api-error.js";
|
|
2
|
-
import {
|
|
3
|
-
import { useCallback as
|
|
4
|
-
import { NotificationVariant as
|
|
2
|
+
import { SKILL_TEXT_FIELD_MAX_LENGTHS as n, buildSkillFilesPayload as r, buildSkillManifestForSubmit as i, getSkillFieldLengthViolations as a, isValidSkillRelativePath as o, normalizeSkillName as s, startsWithFrontmatterBlock as c } from "./skill.js";
|
|
3
|
+
import { useCallback as l, useRef as u, useState as d } from "react";
|
|
4
|
+
import { NotificationVariant as f } from "@epam/ai-dial-ui-kit";
|
|
5
5
|
//#region src/skill/useSkillEditorSubmit.ts
|
|
6
|
-
var
|
|
6
|
+
var p = (e, t) => JSON.stringify({
|
|
7
7
|
values: e,
|
|
8
8
|
files: [...t].sort((e, t) => e.path.localeCompare(t.path))
|
|
9
|
-
}),
|
|
10
|
-
let [
|
|
9
|
+
}), m = ({ bucket: m, isEditMode: h, files: g, filesContentRef: _, frontmatterRef: v, loadedPathRef: y, etagRef: b, returnUrl: x, getCreateReturnUrl: S, refetchSkills: C, client: w, messages: T, onNavigate: E, onNotify: D }) => {
|
|
10
|
+
let [O, k] = d({}), [A, j] = d(), [M, N] = d(!1), [P, F] = d(), [I, L] = d("idle"), R = u(null), z = u(null), B = l(async (n) => {
|
|
11
11
|
switch (t(n)) {
|
|
12
12
|
case 409:
|
|
13
|
-
|
|
13
|
+
k({ name: T.nameConflict });
|
|
14
14
|
return;
|
|
15
15
|
case 412:
|
|
16
|
-
|
|
16
|
+
k({ name: T.nameConflict });
|
|
17
17
|
return;
|
|
18
18
|
case 413:
|
|
19
|
-
|
|
19
|
+
j(T.archiveTooLarge);
|
|
20
20
|
return;
|
|
21
21
|
case 503:
|
|
22
|
-
|
|
22
|
+
j(T.serviceUnavailable), N(!0);
|
|
23
23
|
return;
|
|
24
24
|
case 400: {
|
|
25
25
|
let { message: t } = await e(n);
|
|
26
|
-
|
|
26
|
+
j(t ?? T.pathInvalid);
|
|
27
27
|
return;
|
|
28
28
|
}
|
|
29
29
|
default: {
|
|
30
30
|
let { traceId: t } = await e(n);
|
|
31
|
-
|
|
32
|
-
variant:
|
|
33
|
-
message:
|
|
31
|
+
j(T.saveError), D({
|
|
32
|
+
variant: f.Error,
|
|
33
|
+
message: T.saveError,
|
|
34
34
|
requestId: t
|
|
35
35
|
});
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
-
}, [
|
|
39
|
-
let t =
|
|
40
|
-
if (!t || !
|
|
41
|
-
|
|
38
|
+
}, [T, D]), V = l(async (e) => {
|
|
39
|
+
let t = s(e.name);
|
|
40
|
+
if (!t || !o(t)) {
|
|
41
|
+
k({ name: T.nameInvalid });
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
44
|
-
let
|
|
45
|
-
c ? {skillManifest:
|
|
46
|
-
fingerprint:
|
|
47
|
-
bucket:
|
|
48
|
-
path:
|
|
49
|
-
skillManifest:
|
|
50
|
-
filePaths:
|
|
51
|
-
files:
|
|
44
|
+
let n = p(e, g), a = R.current, c = a != null && a.fingerprint === n, l = t, u, d, h;
|
|
45
|
+
c ? {skillManifest: u, filePaths: d, files: h} = a : (u = i(v.current, t, e.description, e.instructions), {filePaths: d, files: h} = r(g, _.current)), L("submitting"), R.current = {
|
|
46
|
+
fingerprint: n,
|
|
47
|
+
bucket: m,
|
|
48
|
+
path: l,
|
|
49
|
+
skillManifest: u,
|
|
50
|
+
filePaths: d,
|
|
51
|
+
files: h
|
|
52
52
|
};
|
|
53
53
|
try {
|
|
54
|
-
await
|
|
55
|
-
variant:
|
|
56
|
-
title:
|
|
57
|
-
message:
|
|
58
|
-
}), S(
|
|
54
|
+
await w.createSkill(m, l, u, d, h), await C(), L("success"), D({
|
|
55
|
+
variant: f.Success,
|
|
56
|
+
title: T.saveSuccessTitle,
|
|
57
|
+
message: T.createSuccess(t)
|
|
58
|
+
}), E(S?.(l) ?? x);
|
|
59
59
|
} catch (e) {
|
|
60
|
-
|
|
60
|
+
L("failure"), await B(e);
|
|
61
61
|
}
|
|
62
62
|
}, [
|
|
63
|
-
d,
|
|
64
|
-
p,
|
|
65
63
|
m,
|
|
66
|
-
|
|
64
|
+
g,
|
|
65
|
+
_,
|
|
66
|
+
v,
|
|
67
|
+
T,
|
|
68
|
+
w,
|
|
69
|
+
D,
|
|
70
|
+
E,
|
|
67
71
|
x,
|
|
68
|
-
b,
|
|
69
|
-
C,
|
|
70
72
|
S,
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
D(x.saveError);
|
|
73
|
+
C,
|
|
74
|
+
B
|
|
75
|
+
]), H = l(async (e) => {
|
|
76
|
+
let n = y.current, a = b.current;
|
|
77
|
+
if (!n || !a) {
|
|
78
|
+
j(T.saveError);
|
|
78
79
|
return;
|
|
79
80
|
}
|
|
80
|
-
let o =
|
|
81
|
-
|
|
81
|
+
let o = i(v.current, e.name, e.description, e.instructions), { filePaths: s, files: c } = r(g, _.current);
|
|
82
|
+
L("submitting");
|
|
82
83
|
try {
|
|
83
|
-
|
|
84
|
-
variant:
|
|
85
|
-
title:
|
|
86
|
-
message:
|
|
87
|
-
}),
|
|
84
|
+
b.current = (await w.updateSkill(m, n, o, s, c, a)).etag ?? a, await C(), L("success"), D({
|
|
85
|
+
variant: f.Success,
|
|
86
|
+
title: T.updateSuccessTitle,
|
|
87
|
+
message: T.updateSuccess(e.name)
|
|
88
|
+
}), E(x);
|
|
88
89
|
} catch (e) {
|
|
89
|
-
if (
|
|
90
|
-
|
|
90
|
+
if (L("failure"), t(e) === 412) {
|
|
91
|
+
F({ message: T.conflictMessage });
|
|
91
92
|
return;
|
|
92
93
|
}
|
|
93
|
-
await
|
|
94
|
+
await B(e);
|
|
94
95
|
}
|
|
95
96
|
}, [
|
|
96
|
-
d,
|
|
97
|
-
p,
|
|
98
97
|
m,
|
|
99
|
-
h,
|
|
100
98
|
g,
|
|
101
99
|
_,
|
|
102
|
-
x,
|
|
103
|
-
b,
|
|
104
|
-
C,
|
|
105
|
-
S,
|
|
106
100
|
v,
|
|
107
101
|
y,
|
|
108
|
-
|
|
102
|
+
b,
|
|
103
|
+
T,
|
|
104
|
+
w,
|
|
105
|
+
D,
|
|
106
|
+
E,
|
|
107
|
+
x,
|
|
108
|
+
C,
|
|
109
|
+
B
|
|
110
|
+
]), U = l((e) => {
|
|
111
|
+
let t = c(e.instructions), r = a(e);
|
|
112
|
+
k((e) => {
|
|
113
|
+
let i = { ...e };
|
|
114
|
+
for (let e of Object.keys(n)) {
|
|
115
|
+
let t = T.tooLong(n[e]);
|
|
116
|
+
r[e] ? i[e] = t : i[e] === t && delete i[e];
|
|
117
|
+
}
|
|
118
|
+
if (!r.instructions) {
|
|
119
|
+
let e = i.instructions === T.instructionsFrontmatter;
|
|
120
|
+
t && !e ? i.instructions = T.instructionsFrontmatter : !t && e && delete i.instructions;
|
|
121
|
+
}
|
|
122
|
+
return Object.keys(i).length === Object.keys(e).length && Object.keys(i).every((t) => i[t] === e[t]) ? e : i;
|
|
123
|
+
});
|
|
124
|
+
}, [T]), W = l(async (e) => {
|
|
125
|
+
if (I === "submitting" || !m) return;
|
|
126
|
+
let t = {};
|
|
127
|
+
e.name.trim() || (t.name = T.required), e.description.trim() || (t.description = T.required), e.instructions.trim() ? c(e.instructions) && (t.instructions = T.instructionsFrontmatter) : t.instructions = T.required;
|
|
128
|
+
let r = a(e);
|
|
129
|
+
for (let e of Object.keys(r)) t[e] ??= T.tooLong(n[e]);
|
|
130
|
+
if (Object.keys(t).length > 0) {
|
|
131
|
+
k(t);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
k({}), j(void 0), N(!1), F(void 0), z.current = e, h ? await H(e) : await V(e);
|
|
135
|
+
}, [
|
|
136
|
+
I,
|
|
137
|
+
m,
|
|
138
|
+
T,
|
|
139
|
+
h,
|
|
140
|
+
H,
|
|
141
|
+
V
|
|
109
142
|
]);
|
|
110
143
|
return {
|
|
111
|
-
phase:
|
|
112
|
-
errors:
|
|
113
|
-
submitError:
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
T({}), D(void 0), k(void 0), f ? await F(e) : await P(e);
|
|
124
|
-
}, [
|
|
125
|
-
A,
|
|
126
|
-
d,
|
|
127
|
-
x,
|
|
128
|
-
f,
|
|
129
|
-
F,
|
|
130
|
-
P
|
|
131
|
-
])
|
|
144
|
+
phase: I,
|
|
145
|
+
errors: O,
|
|
146
|
+
submitError: A,
|
|
147
|
+
isSubmitErrorRetryable: M,
|
|
148
|
+
retrySubmit: l(() => {
|
|
149
|
+
let e = z.current;
|
|
150
|
+
e != null && W(e);
|
|
151
|
+
}, [W]),
|
|
152
|
+
conflict: P,
|
|
153
|
+
clearConflict: () => F(void 0),
|
|
154
|
+
handleSubmit: W,
|
|
155
|
+
handleValuesChange: U
|
|
132
156
|
};
|
|
133
157
|
};
|
|
134
158
|
//#endregion
|
|
135
|
-
export {
|
|
159
|
+
export { m as useSkillEditorSubmit };
|
|
@@ -1,99 +1,111 @@
|
|
|
1
|
-
import { SKILL_MANIFEST_FILE as e, buildSkillManifest as t, buildSkillManifestFromFrontmatter as n,
|
|
2
|
-
import { validateSkillFileBatch as
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { SKILL_MANIFEST_FILE as e, buildSkillManifest as t, buildSkillManifestFromFrontmatter as n, isValidSkillRelativePath as r, nameFromPath as i } from "./skill.js";
|
|
2
|
+
import { validateSkillFileBatch as a } from "./skill-file-batch-validation.js";
|
|
3
|
+
import { extractSkillArchive as o } from "./skill-archive.js";
|
|
4
|
+
import { getUtf8ByteLength as s } from "@epam/ai-dial-chat-shared";
|
|
5
|
+
import { useCallback as c, useMemo as l, useRef as u, useState as d } from "react";
|
|
6
|
+
import { SkillFileNodeKind as f } from "@epam/ai-dial-skill-editor";
|
|
6
7
|
//#region src/skill/useSkillFileActions.ts
|
|
7
|
-
var
|
|
8
|
-
let [
|
|
9
|
-
let e =
|
|
10
|
-
for (let t of e) r +=
|
|
8
|
+
var p = "probe", m = ({ files: m, setFiles: h, filesContentRef: g, frontmatterRef: _, loadedValues: v, setLoadedValues: y, isEditMode: b, isDirty: x, setSelectedPath: S, messages: C, pickFromFileSystem: w }) => {
|
|
9
|
+
let [T, E] = d(!1), D = u(null), O = c(() => {
|
|
10
|
+
let e = m.filter((e) => e.kind === f.File).map((e) => e.path), r = 0;
|
|
11
|
+
for (let t of e) r += g.current.get(t)?.bytes.length ?? 0;
|
|
11
12
|
let i = {
|
|
12
|
-
name:
|
|
13
|
-
description:
|
|
14
|
-
instructions:
|
|
15
|
-
},
|
|
13
|
+
name: v?.name ?? "",
|
|
14
|
+
description: v?.description ?? "",
|
|
15
|
+
instructions: v?.instructions ?? ""
|
|
16
|
+
}, a = b ? n(_.current, i.name, i.description, i.instructions) : t(i);
|
|
16
17
|
return {
|
|
17
18
|
existingPaths: e,
|
|
18
19
|
existingTotalBytes: r,
|
|
19
|
-
manifestByteLength: a
|
|
20
|
-
messages:
|
|
20
|
+
manifestByteLength: s(a),
|
|
21
|
+
messages: C
|
|
21
22
|
};
|
|
22
23
|
}, [
|
|
23
|
-
d,
|
|
24
|
-
p,
|
|
25
|
-
_,
|
|
26
24
|
m,
|
|
27
|
-
|
|
28
|
-
b
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
g,
|
|
26
|
+
b,
|
|
27
|
+
_,
|
|
28
|
+
v,
|
|
29
|
+
C
|
|
30
|
+
]), k = c(() => new Promise((e) => {
|
|
31
|
+
D.current = e, E(!0);
|
|
32
|
+
}), []), A = c((e) => {
|
|
33
|
+
E(!1), D.current?.(e), D.current = null;
|
|
33
34
|
}, []);
|
|
34
35
|
return {
|
|
35
|
-
fileActions:
|
|
36
|
+
fileActions: l(() => ({
|
|
36
37
|
validateBatch: async (e) => {
|
|
37
|
-
let { results: t, batchErrors: n } = await
|
|
38
|
+
let { results: t, batchErrors: n } = await a(e, O());
|
|
38
39
|
return {
|
|
39
40
|
results: t,
|
|
40
41
|
batchErrors: n
|
|
41
42
|
};
|
|
42
43
|
},
|
|
43
44
|
commitBatch: async (e) => {
|
|
44
|
-
let { results: t, batchErrors: n, manifestCandidate:
|
|
45
|
-
if (t.some((e) => e.error !== void 0) || n.length > 0) return { error: n[0]?.message ??
|
|
46
|
-
if (
|
|
47
|
-
if (
|
|
48
|
-
if ((
|
|
45
|
+
let { results: t, batchErrors: n, manifestCandidate: r } = await a(e, O());
|
|
46
|
+
if (t.some((e) => e.error !== void 0) || n.length > 0) return { error: n[0]?.message ?? C.saveError };
|
|
47
|
+
if (r) {
|
|
48
|
+
if (b && r.name !== (v?.name ?? "")) return { error: C.manifestNameMismatch };
|
|
49
|
+
if ((b || x) && !await k()) return { error: C.manifestImportDeclined };
|
|
49
50
|
}
|
|
50
51
|
try {
|
|
51
|
-
let t = e.filter((e) => e.id !==
|
|
52
|
+
let t = e.filter((e) => e.id !== r?.candidateId), n = await Promise.all(t.map(async (e) => ({
|
|
52
53
|
path: e.path,
|
|
53
54
|
bytes: new Uint8Array(await e.file.arrayBuffer()),
|
|
54
55
|
mimeType: e.file.type || void 0
|
|
55
56
|
})));
|
|
56
|
-
for (let e of n)
|
|
57
|
+
for (let e of n) g.current.set(e.path, {
|
|
57
58
|
bytes: e.bytes,
|
|
58
59
|
mimeType: e.mimeType
|
|
59
60
|
});
|
|
60
|
-
return n.length > 0 &&
|
|
61
|
+
return n.length > 0 && h((e) => [...e, ...n.map((e) => ({
|
|
61
62
|
path: e.path,
|
|
62
|
-
name:
|
|
63
|
-
kind:
|
|
64
|
-
}))]),
|
|
65
|
-
...
|
|
66
|
-
...
|
|
67
|
-
} :
|
|
68
|
-
name:
|
|
69
|
-
description:
|
|
70
|
-
instructions:
|
|
63
|
+
name: i(e.path),
|
|
64
|
+
kind: f.File
|
|
65
|
+
}))]), r && (_.current = b ? {
|
|
66
|
+
..._.current,
|
|
67
|
+
...r.frontmatter
|
|
68
|
+
} : r.frontmatter, y({
|
|
69
|
+
name: b ? v?.name ?? r.name : r.name,
|
|
70
|
+
description: r.description,
|
|
71
|
+
instructions: r.instructions
|
|
71
72
|
})), {};
|
|
72
73
|
} catch (e) {
|
|
73
74
|
return { error: e instanceof Error ? e.message : String(e) };
|
|
74
75
|
}
|
|
75
76
|
},
|
|
76
77
|
onRemoveNode: (t) => {
|
|
77
|
-
|
|
78
|
-
for (let e of [...
|
|
79
|
-
|
|
80
|
-
}
|
|
78
|
+
h((e) => e.filter((e) => e.path !== t && !e.path.startsWith(`${t}/`)));
|
|
79
|
+
for (let e of [...g.current.keys()]) (e === t || e.startsWith(`${t}/`)) && g.current.delete(e);
|
|
80
|
+
S((n) => n === t || n.startsWith(`${t}/`) ? e : n);
|
|
81
|
+
},
|
|
82
|
+
onCreateFolder: (e) => {
|
|
83
|
+
h((t) => t.some((t) => t.path === e) ? t : [...t, {
|
|
84
|
+
path: e,
|
|
85
|
+
name: i(e),
|
|
86
|
+
kind: f.Folder
|
|
87
|
+
}]);
|
|
88
|
+
},
|
|
89
|
+
validateFolderPath: (e) => r(`${e}/${p}`) ? void 0 : C.pathInvalid,
|
|
90
|
+
extractArchive: o,
|
|
91
|
+
pickFromFileSystem: w
|
|
81
92
|
}), [
|
|
82
|
-
|
|
83
|
-
|
|
93
|
+
O,
|
|
94
|
+
b,
|
|
95
|
+
x,
|
|
84
96
|
v,
|
|
85
|
-
|
|
86
|
-
T,
|
|
87
|
-
p,
|
|
88
|
-
m,
|
|
89
|
-
f,
|
|
97
|
+
k,
|
|
90
98
|
g,
|
|
99
|
+
_,
|
|
100
|
+
h,
|
|
91
101
|
y,
|
|
92
|
-
|
|
102
|
+
S,
|
|
103
|
+
C,
|
|
104
|
+
w
|
|
93
105
|
]),
|
|
94
|
-
pendingManifestImport:
|
|
95
|
-
resolveManifestImport:
|
|
106
|
+
pendingManifestImport: T,
|
|
107
|
+
resolveManifestImport: A
|
|
96
108
|
};
|
|
97
109
|
};
|
|
98
110
|
//#endregion
|
|
99
|
-
export {
|
|
111
|
+
export { m as useSkillFileActions };
|
package/skill-editor.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { SkillEditorFileActions } from '@epam/ai-dial-skill-editor';
|
|
|
7
7
|
import { SkillEditorValues } from '@epam/ai-dial-skill-editor';
|
|
8
8
|
import { SkillFileBatchError } from '@epam/ai-dial-skill-editor';
|
|
9
9
|
import { SkillFileListResponseDto } from '@epam/ai-dial-chat-api-client';
|
|
10
|
+
import { SkillFileSourceEntry } from '@epam/ai-dial-skill-editor';
|
|
10
11
|
import { SkillFileTreeNode } from '@epam/ai-dial-skill-editor';
|
|
11
12
|
import { SkillFileUploadCandidate } from '@epam/ai-dial-skill-editor';
|
|
12
13
|
import { SkillFileValidationResult } from '@epam/ai-dial-skill-editor';
|
|
@@ -43,6 +44,16 @@ export declare const buildSkillManifestForSubmit: (frontmatter: Record<string, u
|
|
|
43
44
|
*/
|
|
44
45
|
export declare const buildSkillManifestFromFrontmatter: (baseFrontmatter: Record<string, unknown>, name: string, description: string, instructions: string) => string;
|
|
45
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Classifies an import request's HTTP status into a semantic outcome: 400/413/422 are
|
|
49
|
+
* archive-content problems, 409 is a name collision, 429 is rate limiting, 502/503 mean the
|
|
50
|
+
* backend is unavailable, and anything else (including no status at all) is generic.
|
|
51
|
+
*/
|
|
52
|
+
export declare const classifySkillArchiveImportError: (status: number | undefined) => SkillArchiveImportErrorKind;
|
|
53
|
+
|
|
54
|
+
/** Returns the limit each over-long skill field exceeds, keyed by field; fields within their limit are omitted. */
|
|
55
|
+
export declare const getSkillFieldLengthViolations: (values: Record<SkillTextField, string>) => Partial<Record<SkillTextField, number>>;
|
|
56
|
+
|
|
46
57
|
/**
|
|
47
58
|
* Client-side mirror of the backend's `isValidSkillRelativePath`
|
|
48
59
|
* (`apps/chat-api/src/skills/utils/skill-path.util.ts`), used only for
|
|
@@ -98,6 +109,9 @@ export declare const SKILL_FILE_UPLOAD_MAX_BYTES = 1048576;
|
|
|
98
109
|
/** Root manifest filename required at the top of every skill archive (mirrors `SKILL_MANIFEST_FILE` in `apps/chat-api/src/skills/utils/skill-path.util.ts`). */
|
|
99
110
|
export declare const SKILL_MANIFEST_FILE = "SKILL.md";
|
|
100
111
|
|
|
112
|
+
/** Length limit of each skill editor text field. */
|
|
113
|
+
export declare const SKILL_TEXT_FIELD_MAX_LENGTHS: Record<SkillTextField, number>;
|
|
114
|
+
|
|
101
115
|
/**
|
|
102
116
|
* Client-side mirror of the backend's default `SKILL_UPLOAD_MAX_FILES`
|
|
103
117
|
* (`apps/chat-api/src/config/environment.config.ts`), used only for
|
|
@@ -122,6 +136,28 @@ export declare interface SkillAboutDetails {
|
|
|
122
136
|
skillPrompt?: string;
|
|
123
137
|
}
|
|
124
138
|
|
|
139
|
+
/** Semantic classification of an import request failure. */
|
|
140
|
+
export declare enum SkillArchiveImportErrorKind {
|
|
141
|
+
Validation = "validation",
|
|
142
|
+
Collision = "collision",
|
|
143
|
+
RateLimited = "rateLimited",
|
|
144
|
+
ServiceUnavailable = "serviceUnavailable",
|
|
145
|
+
Generic = "generic"
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** Phase of a skill-archive import, driving the host's loading/success/error presentation. */
|
|
149
|
+
export declare enum SkillArchiveImportStatus {
|
|
150
|
+
Idle = "idle",
|
|
151
|
+
Uploading = "uploading",
|
|
152
|
+
Success = "success",
|
|
153
|
+
Error = "error"
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** Reason a selected/dropped file was rejected before any request was made. */
|
|
157
|
+
export declare enum SkillArchiveSelectionRejectionReason {
|
|
158
|
+
UnsupportedFilename = "unsupportedFilename"
|
|
159
|
+
}
|
|
160
|
+
|
|
125
161
|
/** Already-configured DIAL Core download operations `useSkillEditorLoad` needs. */
|
|
126
162
|
export declare interface SkillEditorLoadClient {
|
|
127
163
|
/** Downloads the whole-skill ZIP archive. */
|
|
@@ -163,6 +199,14 @@ export declare interface SkillEditorSubmitClient {
|
|
|
163
199
|
export declare interface SkillEditorSubmitMessages {
|
|
164
200
|
/** Shown when a required field is empty. */
|
|
165
201
|
required: string;
|
|
202
|
+
/** Shown when a name, description or instructions value exceeds its length limit, given that limit. */
|
|
203
|
+
tooLong: (maxLength: number) => string;
|
|
204
|
+
/**
|
|
205
|
+
* Shown when the Instructions value opens with its own YAML frontmatter
|
|
206
|
+
* block — pasting a whole `SKILL.md` in there would otherwise produce a
|
|
207
|
+
* manifest with two frontmatter blocks.
|
|
208
|
+
*/
|
|
209
|
+
instructionsFrontmatter: string;
|
|
166
210
|
/** Shown when the normalized skill name fails DIAL's naming rules. */
|
|
167
211
|
nameInvalid: string;
|
|
168
212
|
/** Shown when the skill name already exists (409), or defensively on an unreachable create-mode 412. */
|
|
@@ -328,6 +372,31 @@ export declare interface SkillManifestValues {
|
|
|
328
372
|
instructions: string;
|
|
329
373
|
}
|
|
330
374
|
|
|
375
|
+
/** Skill editor text fields with a length limit. */
|
|
376
|
+
export declare type SkillTextField = 'name' | 'description' | 'instructions';
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Answers one question: would appending this text after the fence that
|
|
380
|
+
* `buildSkillManifest` writes produce a *second* frontmatter block?
|
|
381
|
+
*
|
|
382
|
+
* That happens when the text's first non-blank line is a bare `---` and some
|
|
383
|
+
* later line is a bare `---` too — the exact shape of a `SKILL.md` pasted
|
|
384
|
+
* wholesale into the editor's Instructions field.
|
|
385
|
+
*
|
|
386
|
+
* Detection is deliberately structural rather than YAML-based: a pasted block
|
|
387
|
+
* whose fenced content fails to parse corrupts the stored manifest
|
|
388
|
+
* identically (and renders as a setext `h2` in the Catalog's Details tab just
|
|
389
|
+
* the same), so requiring parseable YAML here would let the worst cases
|
|
390
|
+
* through. Keeping `parseYaml` out also makes this cheap enough to run on
|
|
391
|
+
* every keystroke.
|
|
392
|
+
*
|
|
393
|
+
* A single unclosed fence returns `false`: with no closing fence there is no
|
|
394
|
+
* second block, matching `FRONTMATTER_PATTERN`'s own requirement. A `---`
|
|
395
|
+
* appearing later in the body (a horizontal rule, a setext underline) is
|
|
396
|
+
* likewise not a frontmatter block.
|
|
397
|
+
*/
|
|
398
|
+
export declare const startsWithFrontmatterBlock: (text: string) => boolean;
|
|
399
|
+
|
|
331
400
|
declare type SubmitPhase = 'idle' | 'submitting' | 'success' | 'failure';
|
|
332
401
|
|
|
333
402
|
/** A skill archive unpacked into its manifest text and a relative-path → bytes map of every other entry. */
|
|
@@ -346,6 +415,48 @@ export declare interface UnpackedSkillArchive {
|
|
|
346
415
|
*/
|
|
347
416
|
export declare const unpackSkillArchive: (bytes: Uint8Array) => UnpackedSkillArchive;
|
|
348
417
|
|
|
418
|
+
/**
|
|
419
|
+
* Headless controller for the skill-archive upload flow: dialog visibility, the exact-filename
|
|
420
|
+
* precheck, in-flight exclusion, abort-on-close, and import completion. The host supplies the configured request
|
|
421
|
+
* and observes completion/failure through the injected callbacks; the hook never imports app
|
|
422
|
+
* contexts, i18n, or a configured API client.
|
|
423
|
+
*/
|
|
424
|
+
export declare const useSkillArchiveImport: <TResult>({ importArchive, onImported, onError, manifestFileName, }: UseSkillArchiveImportOptions<TResult>) => UseSkillArchiveImportResult;
|
|
425
|
+
|
|
426
|
+
/** Options accepted by {@link useSkillArchiveImport}. */
|
|
427
|
+
export declare interface UseSkillArchiveImportOptions<TResult> {
|
|
428
|
+
/** Submits the selected archive; the host owns the client. `signal` aborts when the dialog closes or the hook unmounts mid-upload. */
|
|
429
|
+
importArchive: (file: File, signal: AbortSignal) => Promise<TResult>;
|
|
430
|
+
/** Called once after a successful import (and any awaited host follow-up) settles. */
|
|
431
|
+
onImported: (result: TResult) => void | Promise<void>;
|
|
432
|
+
/** Called once when the import request, or the host's follow-up in {@link onImported}, fails. */
|
|
433
|
+
onError: (error: unknown, kind: SkillArchiveImportErrorKind) => void;
|
|
434
|
+
/** Exact filename treated as the skill manifest. Defaults to `'SKILL.md'`. */
|
|
435
|
+
manifestFileName?: string;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/** Result returned by {@link useSkillArchiveImport}. */
|
|
439
|
+
export declare interface UseSkillArchiveImportResult {
|
|
440
|
+
/** Whether the upload dialog is open. */
|
|
441
|
+
isDialogOpen: boolean;
|
|
442
|
+
/** Current phase of the import. */
|
|
443
|
+
status: SkillArchiveImportStatus;
|
|
444
|
+
/** Whether an import request is in flight; the dialog stays open until it succeeds. */
|
|
445
|
+
isUploading: boolean;
|
|
446
|
+
/** Reason the current/last selection was rejected locally; `undefined` once cleared. */
|
|
447
|
+
selectionRejectionReason: SkillArchiveSelectionRejectionReason | undefined;
|
|
448
|
+
/** Classified failure of the last import request; `undefined` outside a request failure. */
|
|
449
|
+
errorKind: SkillArchiveImportErrorKind | undefined;
|
|
450
|
+
/** Opens the dialog and clears any previous rejection or request failure. */
|
|
451
|
+
openDialog: () => void;
|
|
452
|
+
/** Closes the dialog, aborting an in-flight import, and clears any rejection reason. */
|
|
453
|
+
closeDialog: () => void;
|
|
454
|
+
/** Wire to the dialog drop zone's `onChange`. */
|
|
455
|
+
handleFilesSelected: (files: File[]) => void;
|
|
456
|
+
/** Wire to the dialog drop zone's `onReject`. */
|
|
457
|
+
handleFilesRejected: () => void;
|
|
458
|
+
}
|
|
459
|
+
|
|
349
460
|
/**
|
|
350
461
|
* Owns the edit-mode skill download/unpack/parse flow: the in-memory
|
|
351
462
|
* supporting-file map, the loaded manifest values and frontmatter, the
|
|
@@ -397,7 +508,7 @@ export declare interface UseSkillEditorLoadResult {
|
|
|
397
508
|
* `client.createSkill`/`client.updateSkill`, and mapping the resulting
|
|
398
509
|
* success/error/conflict outcomes to presentable state.
|
|
399
510
|
*/
|
|
400
|
-
export declare const useSkillEditorSubmit: ({ bucket, isEditMode, files, filesContentRef, frontmatterRef, loadedPathRef, etagRef, returnUrl, refetchSkills, client, messages, onNavigate, onNotify, }: UseSkillEditorSubmitParams) => UseSkillEditorSubmitResult;
|
|
511
|
+
export declare const useSkillEditorSubmit: ({ bucket, isEditMode, files, filesContentRef, frontmatterRef, loadedPathRef, etagRef, returnUrl, getCreateReturnUrl, refetchSkills, client, messages, onNavigate, onNotify, }: UseSkillEditorSubmitParams) => UseSkillEditorSubmitResult;
|
|
401
512
|
|
|
402
513
|
/** Parameters accepted by {@link useSkillEditorSubmit}. */
|
|
403
514
|
export declare interface UseSkillEditorSubmitParams {
|
|
@@ -417,6 +528,8 @@ export declare interface UseSkillEditorSubmitParams {
|
|
|
417
528
|
etagRef: React.MutableRefObject<string | undefined>;
|
|
418
529
|
/** Where to navigate on a successful save. */
|
|
419
530
|
returnUrl: string;
|
|
531
|
+
/** Resolves the destination after creation from the normalized skill path. Defaults to `returnUrl`. */
|
|
532
|
+
getCreateReturnUrl?: (path: string) => string;
|
|
420
533
|
/** Refetches the host's skill listing after a successful save. */
|
|
421
534
|
refetchSkills: () => Promise<void>;
|
|
422
535
|
/** Already-configured create/update operations. */
|
|
@@ -437,6 +550,10 @@ export declare interface UseSkillEditorSubmitResult {
|
|
|
437
550
|
errors: SkillEditorErrors;
|
|
438
551
|
/** General submit-time error, distinct from a stale-edit `conflict`. */
|
|
439
552
|
submitError: string | undefined;
|
|
553
|
+
/** Whether `submitError` was caused by something a plain re-send can clear, rather than by the submission itself. */
|
|
554
|
+
isSubmitErrorRetryable: boolean;
|
|
555
|
+
/** Re-submits the values of the attempt that produced `submitError`. No-op before the first submit. */
|
|
556
|
+
retrySubmit: () => void;
|
|
440
557
|
/** Present when the last save hit a stale-ETag conflict. */
|
|
441
558
|
conflict: {
|
|
442
559
|
message: string;
|
|
@@ -445,15 +562,22 @@ export declare interface UseSkillEditorSubmitResult {
|
|
|
445
562
|
clearConflict: () => void;
|
|
446
563
|
/** Validates and submits the given form values. */
|
|
447
564
|
handleSubmit: (values: SkillEditorValues) => Promise<void>;
|
|
565
|
+
/**
|
|
566
|
+
* Re-runs the Instructions frontmatter check against the editor's current
|
|
567
|
+
* values, so a pasted `SKILL.md` is flagged as the text lands rather than
|
|
568
|
+
* only on submit. Pass as the editor's `onValuesChange`.
|
|
569
|
+
*/
|
|
570
|
+
handleValuesChange: (values: SkillEditorValues) => void;
|
|
448
571
|
}
|
|
449
572
|
|
|
450
573
|
/**
|
|
451
574
|
* Owns the Skill Editor's batch file upload workflow: validating a staged
|
|
452
575
|
* batch, committing it atomically (supporting files plus an optional
|
|
453
|
-
* `SKILL.md` manifest import, with a confirmation gate),
|
|
576
|
+
* `SKILL.md` manifest import, with a confirmation gate), creating empty
|
|
577
|
+
* folders, expanding `.zip` archives for staging, and removing
|
|
454
578
|
* already-committed nodes.
|
|
455
579
|
*/
|
|
456
|
-
export declare const useSkillFileActions: ({ files, setFiles, filesContentRef, frontmatterRef, loadedValues, setLoadedValues, isEditMode, isDirty, setSelectedPath, messages, }: UseSkillFileActionsParams) => UseSkillFileActionsResult;
|
|
580
|
+
export declare const useSkillFileActions: ({ files, setFiles, filesContentRef, frontmatterRef, loadedValues, setLoadedValues, isEditMode, isDirty, setSelectedPath, messages, pickFromFileSystem, }: UseSkillFileActionsParams) => UseSkillFileActionsResult;
|
|
457
581
|
|
|
458
582
|
/** Parameters accepted by {@link useSkillFileActions}. */
|
|
459
583
|
export declare interface UseSkillFileActionsParams {
|
|
@@ -477,6 +601,12 @@ export declare interface UseSkillFileActionsParams {
|
|
|
477
601
|
setSelectedPath: Dispatch<SetStateAction<string>>;
|
|
478
602
|
/** Localized messages, resolved by the host. */
|
|
479
603
|
messages: SkillFileActionsMessages;
|
|
604
|
+
/**
|
|
605
|
+
* Opens the host's file-system picker; passed through unchanged as
|
|
606
|
+
* `fileActions.pickFromFileSystem`. Omit to hide the editor's "Open DIAL
|
|
607
|
+
* file system" entry.
|
|
608
|
+
*/
|
|
609
|
+
pickFromFileSystem?: () => Promise<SkillFileSourceEntry[] | undefined>;
|
|
480
610
|
}
|
|
481
611
|
|
|
482
612
|
/** Return value of {@link useSkillFileActions}. */
|
package/skill-editor.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { SKILL_FILE_UPLOAD_MAX_BYTES as e, SKILL_MANIFEST_FILE as t,
|
|
2
|
-
import { parseSkillManifestDocument as
|
|
3
|
-
import { validateSkillFileBatch as
|
|
4
|
-
import { skillFileToAttachment as
|
|
5
|
-
import { SkillEditorLoadState as
|
|
6
|
-
import { useSkillEditorSubmit as
|
|
7
|
-
import { useSkillFileActions as
|
|
8
|
-
|
|
1
|
+
import { SKILL_FILE_UPLOAD_MAX_BYTES as e, SKILL_MANIFEST_FILE as t, SKILL_TEXT_FIELD_MAX_LENGTHS as n, SKILL_UPLOAD_MAX_FILES as r, SKILL_UPLOAD_MAX_TOTAL_BYTES as i, buildSkillFilesPayload as a, buildSkillManifest as o, buildSkillManifestForSubmit as s, buildSkillManifestFromFrontmatter as c, getSkillFieldLengthViolations as l, isValidSkillRelativePath as u, nameFromPath as d, normalizeSkillName as f, parseSkillManifest as p, skillFileBytesToBlob as m, startsWithFrontmatterBlock as h, unpackSkillArchive as g } from "./skill/skill.js";
|
|
2
|
+
import { parseSkillManifestDocument as _ } from "./skill/skill-manifest.js";
|
|
3
|
+
import { validateSkillFileBatch as v } from "./skill/skill-file-batch-validation.js";
|
|
4
|
+
import { skillFileToAttachment as y } from "./skill/skill-file-preview.js";
|
|
5
|
+
import { SkillEditorLoadState as b, useSkillEditorLoad as x } from "./skill/useSkillEditorLoad.js";
|
|
6
|
+
import { useSkillEditorSubmit as S } from "./skill/useSkillEditorSubmit.js";
|
|
7
|
+
import { useSkillFileActions as C } from "./skill/useSkillFileActions.js";
|
|
8
|
+
import { SkillArchiveImportErrorKind as w, SkillArchiveImportStatus as T, SkillArchiveSelectionRejectionReason as E, classifySkillArchiveImportError as D, useSkillArchiveImport as O } from "./skill/useSkillArchiveImport/useSkillArchiveImport.js";
|
|
9
|
+
export { e as SKILL_FILE_UPLOAD_MAX_BYTES, t as SKILL_MANIFEST_FILE, n as SKILL_TEXT_FIELD_MAX_LENGTHS, r as SKILL_UPLOAD_MAX_FILES, i as SKILL_UPLOAD_MAX_TOTAL_BYTES, w as SkillArchiveImportErrorKind, T as SkillArchiveImportStatus, E as SkillArchiveSelectionRejectionReason, b as SkillEditorLoadState, a as buildSkillFilesPayload, o as buildSkillManifest, s as buildSkillManifestForSubmit, c as buildSkillManifestFromFrontmatter, D as classifySkillArchiveImportError, l as getSkillFieldLengthViolations, u as isValidSkillRelativePath, d as nameFromPath, f as normalizeSkillName, p as parseSkillManifest, _ as parseSkillManifestDocument, m as skillFileBytesToBlob, y as skillFileToAttachment, h as startsWithFrontmatterBlock, g as unpackSkillArchive, O as useSkillArchiveImport, x as useSkillEditorLoad, S as useSkillEditorSubmit, C as useSkillFileActions, v as validateSkillFileBatch };
|