@epam/ai-dial-chat-hooks 1.2.0-dev.20 → 1.2.0-dev.201
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/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 +183 -108
- 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 +1066 -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 +75 -0
- package/skill/useSkillEditorLoad.js +29 -28
- package/skill/useSkillEditorSubmit.js +108 -84
- package/skill/useSkillFileActions.js +70 -58
- package/skill-editor.d.ts +131 -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,4 +1,5 @@
|
|
|
1
|
-
import { OAuthResourceKind as e, ToolsetAuthStatus as t, ToolsetAuthTypes as n,
|
|
1
|
+
import { OAuthResourceKind as e, ToolsetAuthStatus as t, ToolsetAuthTypes as n, ToolsetOAuthInitiationResultType as r, ToolsetOAuthResultType as i } from "../types.js";
|
|
2
|
+
import { selectToolsetAuthStatus as a } from "../toolset-id.js";
|
|
2
3
|
import { emitToolsetLoginSuccess as o } from "../../shared/toolset-login-events.js";
|
|
3
4
|
import { waitForToolsetOAuthResult as s } from "../handshake.js";
|
|
4
5
|
import { initiateOAuthLogin as c, navigateToolsetOAuthPopup as l, openToolsetOAuthPopup as u } from "../popup.js";
|
|
@@ -24,23 +25,22 @@ var f = /* @__PURE__ */ function(e) {
|
|
|
24
25
|
codeChallengeMethod: _?.codeChallengeMethod
|
|
25
26
|
}, x = v ? await (async () => {
|
|
26
27
|
let t = u();
|
|
27
|
-
return t ? (await g(p, m, n.OAuth), l(t, b, p, f, m, e.Toolset, y)) : { type:
|
|
28
|
+
return t ? (await g(p, m, n.OAuth), l(t, b, p, f, m, e.Toolset, y)) : { type: r.Blocked };
|
|
28
29
|
})() : c(b, p, f, m, y);
|
|
29
|
-
if (x.type ===
|
|
30
|
-
if (x.type !==
|
|
30
|
+
if (x.type === r.Blocked) return { type: "popup-blocked" };
|
|
31
|
+
if (x.type !== r.Started) return { type: "failure" };
|
|
31
32
|
let S = await s(x.popup, x.flowId, {
|
|
32
33
|
toolsetId: p,
|
|
33
34
|
credentialsLevel: m,
|
|
34
35
|
callbackPath: f
|
|
35
36
|
});
|
|
36
|
-
if (S.type ===
|
|
37
|
+
if (S.type === i.Success) return o({
|
|
37
38
|
toolsetId: p,
|
|
38
39
|
credentialsLevel: m
|
|
39
40
|
}), { type: "success" };
|
|
40
|
-
if (S.type ===
|
|
41
|
+
if (S.type === i.Failure) return { type: "failure" };
|
|
41
42
|
try {
|
|
42
|
-
|
|
43
|
-
if ((m === r.User ? e.authSettings?.userLevelAuthStatus : e.authSettings?.globalAuthStatus) === t.SignedIn) return o({
|
|
43
|
+
if (a((await h(p)).authSettings, m) === t.SignedIn) return o({
|
|
44
44
|
toolsetId: p,
|
|
45
45
|
credentialsLevel: m
|
|
46
46
|
}), { type: "success" };
|
package/oauth.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DialToolsetAuthSettingsDto } from '@epam/ai-dial-chat-api-client';
|
|
1
2
|
import { DialToolsetDto } from '@epam/ai-dial-chat-api-client';
|
|
2
3
|
import { ToolsetLoginBodyDto } from '@epam/ai-dial-chat-api-client';
|
|
3
4
|
import { ToolsetLogoutBodyDto } from '@epam/ai-dial-chat-api-client';
|
|
@@ -74,6 +75,19 @@ export declare const isPublicToolsetId: (toolsetId: string) => boolean;
|
|
|
74
75
|
*/
|
|
75
76
|
export declare const navigateToolsetOAuthPopup: (popup: Window, auth: ToolsetOAuthSettings, toolsetId: string, callbackPath: string, credentialsLevel?: ToolsetCredentialsLevel, resourceKind?: OAuthResourceKind, offlineUsageConsent?: boolean) => ToolsetOAuthInitiationResult;
|
|
76
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Encodes a toolset id to its single-encoded form regardless of whether the
|
|
80
|
+
* value received it in was already percent-encoded or the raw,
|
|
81
|
+
* human-readable form — decoding first then re-encoding once is idempotent
|
|
82
|
+
* either way, since `decodeToolsetId` on a raw (unencoded) id is a no-op.
|
|
83
|
+
* Use this instead of `encodeToolsetId` at a boundary that cannot guarantee
|
|
84
|
+
* which form it receives, such as a `postMessage` payload from an embedded
|
|
85
|
+
* iframe: calling `encodeToolsetId` directly on a value the sender already
|
|
86
|
+
* encoded escapes the existing `%` characters a second time (`%20` becomes
|
|
87
|
+
* `%2520`), which the backend only ever undoes once and so 404s on.
|
|
88
|
+
*/
|
|
89
|
+
export declare const normalizeToolsetId: (toolsetId: string) => string;
|
|
90
|
+
|
|
77
91
|
/** Arguments handed to the host's exchange callback. */
|
|
78
92
|
export declare interface OAuthExchangeParams {
|
|
79
93
|
/** One-time authorization code the provider returned. */
|
|
@@ -115,6 +129,24 @@ export declare enum OAuthResourceKind {
|
|
|
115
129
|
*/
|
|
116
130
|
export declare const openToolsetOAuthPopup: () => Window | null;
|
|
117
131
|
|
|
132
|
+
/**
|
|
133
|
+
* Resolves which credentials level a toolset's login applies to, per DIAL
|
|
134
|
+
* Core's public/private toolset convention: a `public`-bucket toolset is
|
|
135
|
+
* shared credentials-wise at `User` level, while a private/workspace toolset
|
|
136
|
+
* is scoped at `Global` level. Every surface that drives a toolset login
|
|
137
|
+
* (the sign-in-interrupt dialog, the QuickApps editor iframe bridge,
|
|
138
|
+
* `useToolsetLogin`) must resolve the level this way rather than assuming one.
|
|
139
|
+
*/
|
|
140
|
+
export declare const resolveToolsetCredentialsLevel: (toolsetId: string) => ToolsetCredentialsLevel.User | ToolsetCredentialsLevel.Global;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Picks the auth-status field matching one credentials level out of a
|
|
144
|
+
* toolset's `authSettings` — DIAL Core reports `userLevelAuthStatus` and
|
|
145
|
+
* `globalAuthStatus` as independent fields rather than one status keyed by
|
|
146
|
+
* level.
|
|
147
|
+
*/
|
|
148
|
+
export declare const selectToolsetAuthStatus: (authSettings: Pick<DialToolsetAuthSettingsDto, "userLevelAuthStatus" | "globalAuthStatus"> | undefined, credentialsLevel: ToolsetCredentialsLevel) => string | undefined;
|
|
149
|
+
|
|
118
150
|
export declare const subscribeToolsetLoginSuccess: <T>(listener: (detail: ToolsetLoginSuccessDetail<T>) => void) => (() => void);
|
|
119
151
|
|
|
120
152
|
/** `sessionStorage` key the flow writes its `ToolsetRedirectState` under, in the popup it opens. */
|
package/oauth.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { emitToolsetLoginSuccess as
|
|
4
|
-
import { getToolsetOAuthChannelName as
|
|
5
|
-
import { buildToolsetAuthorizeUrl as
|
|
6
|
-
import { initiateOAuthLogin as
|
|
7
|
-
import { ToolsetLoginOutcomeType as
|
|
8
|
-
import { useOAuthCallbackCompletion as
|
|
9
|
-
export {
|
|
1
|
+
import { OAuthResourceKind as e, TOOLSET_REDIRECT_STATE_KEY as t, ToolsetAuthStatus as n, ToolsetAuthTypes as r, ToolsetCredentialsLevel as i, ToolsetOAuthCallbackQuery as a, ToolsetOAuthChannelControlType as o, ToolsetOAuthFailureReason as s, ToolsetOAuthInitiationResultType as c, ToolsetOAuthResultType as l, WithLogin as u } from "./oauth/types.js";
|
|
2
|
+
import { decodeToolsetId as d, encodeToolsetId as f, isPublicToolsetId as p, normalizeToolsetId as m, resolveToolsetCredentialsLevel as h, selectToolsetAuthStatus as g } from "./oauth/toolset-id.js";
|
|
3
|
+
import { emitToolsetLoginSuccess as _, subscribeToolsetLoginSuccess as v } from "./shared/toolset-login-events.js";
|
|
4
|
+
import { getToolsetOAuthChannelName as y, waitForToolsetOAuthResult as b } from "./oauth/handshake.js";
|
|
5
|
+
import { buildToolsetAuthorizeUrl as x, getToolsetRedirectUri as S } from "./oauth/authorize-url.js";
|
|
6
|
+
import { initiateOAuthLogin as C, navigateToolsetOAuthPopup as w, openToolsetOAuthPopup as T } from "./oauth/popup.js";
|
|
7
|
+
import { ToolsetLoginOutcomeType as E, useToolsetLogin as D } from "./oauth/useToolsetLogin/useToolsetLogin.js";
|
|
8
|
+
import { useOAuthCallbackCompletion as O } from "./oauth/useOAuthCallbackCompletion/useOAuthCallbackCompletion.js";
|
|
9
|
+
export { e as OAuthResourceKind, t as TOOLSET_REDIRECT_STATE_KEY, n as ToolsetAuthStatus, r as ToolsetAuthTypes, i as ToolsetCredentialsLevel, E as ToolsetLoginOutcomeType, a as ToolsetOAuthCallbackQuery, o as ToolsetOAuthChannelControlType, s as ToolsetOAuthFailureReason, c as ToolsetOAuthInitiationResultType, l as ToolsetOAuthResultType, u as WithLogin, x as buildToolsetAuthorizeUrl, d as decodeToolsetId, _ as emitToolsetLoginSuccess, f as encodeToolsetId, y as getToolsetOAuthChannelName, S as getToolsetRedirectUri, C as initiateOAuthLogin, p as isPublicToolsetId, w as navigateToolsetOAuthPopup, m as normalizeToolsetId, T as openToolsetOAuthPopup, h as resolveToolsetCredentialsLevel, g as selectToolsetAuthStatus, v as subscribeToolsetLoginSuccess, O as useOAuthCallbackCompletion, D as useToolsetLogin, b as waitForToolsetOAuthResult };
|
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.201",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./index.js",
|
|
@@ -29,6 +29,11 @@
|
|
|
29
29
|
"import": "./conversation.js",
|
|
30
30
|
"default": "./conversation.js"
|
|
31
31
|
},
|
|
32
|
+
"./conversation-overlay": {
|
|
33
|
+
"types": "./conversation-overlay.d.ts",
|
|
34
|
+
"import": "./conversation-overlay.js",
|
|
35
|
+
"default": "./conversation-overlay.js"
|
|
36
|
+
},
|
|
32
37
|
"./conversation-transfer": {
|
|
33
38
|
"types": "./conversation-transfer.d.ts",
|
|
34
39
|
"import": "./conversation-transfer.js",
|
|
@@ -44,6 +49,11 @@
|
|
|
44
49
|
"import": "./file-manager.js",
|
|
45
50
|
"default": "./file-manager.js"
|
|
46
51
|
},
|
|
52
|
+
"./file-manager-canvas": {
|
|
53
|
+
"types": "./file-manager-canvas.d.ts",
|
|
54
|
+
"import": "./file-manager-canvas.js",
|
|
55
|
+
"default": "./file-manager-canvas.js"
|
|
56
|
+
},
|
|
47
57
|
"./source-content": {
|
|
48
58
|
"types": "./source-content.d.ts",
|
|
49
59
|
"import": "./source-content.js",
|
|
@@ -89,6 +99,11 @@
|
|
|
89
99
|
"import": "./utils.js",
|
|
90
100
|
"default": "./utils.js"
|
|
91
101
|
},
|
|
102
|
+
"./usage": {
|
|
103
|
+
"types": "./usage.d.ts",
|
|
104
|
+
"import": "./usage.js",
|
|
105
|
+
"default": "./usage.js"
|
|
106
|
+
},
|
|
92
107
|
"./mcp-apps": {
|
|
93
108
|
"types": "./mcp-apps.d.ts",
|
|
94
109
|
"import": "./mcp-apps.js",
|
|
@@ -96,7 +111,7 @@
|
|
|
96
111
|
}
|
|
97
112
|
},
|
|
98
113
|
"dependencies": {
|
|
99
|
-
"@epam/ai-dial-chat-api-client": "1.2.0-dev.
|
|
114
|
+
"@epam/ai-dial-chat-api-client": "1.2.0-dev.201",
|
|
100
115
|
"dompurify": "3.4.15",
|
|
101
116
|
"fflate": "^0.8.3",
|
|
102
117
|
"lru-cache": "^10.4.3",
|
|
@@ -105,21 +120,21 @@
|
|
|
105
120
|
},
|
|
106
121
|
"peerDependencies": {
|
|
107
122
|
"react": "^19.2.8",
|
|
108
|
-
"@epam/ai-dial-attachment-canvas": "1.2.0-dev.
|
|
109
|
-
"@epam/ai-dial-attachment-input": "1.2.0-dev.
|
|
110
|
-
"@epam/ai-dial-
|
|
111
|
-
"@epam/ai-dial-
|
|
112
|
-
"@epam/ai-dial-chat-
|
|
113
|
-
"@epam/ai-dial-
|
|
114
|
-
"@epam/ai-dial-
|
|
115
|
-
"@epam/ai-dial-
|
|
116
|
-
"@epam/ai-dial-
|
|
117
|
-
"@epam/ai-dial-
|
|
118
|
-
"@epam/ai-dial-
|
|
119
|
-
"@epam/ai-dial-
|
|
120
|
-
"@epam/ai-dial-
|
|
121
|
-
"@epam/ai-dial-
|
|
122
|
-
"@epam/ai-dial-
|
|
123
|
+
"@epam/ai-dial-attachment-canvas": "1.2.0-dev.201",
|
|
124
|
+
"@epam/ai-dial-attachment-input": "1.2.0-dev.201",
|
|
125
|
+
"@epam/ai-dial-catalog": "1.2.0-dev.201",
|
|
126
|
+
"@epam/ai-dial-chat-overlay": "1.2.0-dev.201",
|
|
127
|
+
"@epam/ai-dial-chat-shared": "1.2.0-dev.201",
|
|
128
|
+
"@epam/ai-dial-mcp-apps": "1.2.0-dev.201",
|
|
129
|
+
"@epam/ai-dial-publish-panel": "1.2.0-dev.201",
|
|
130
|
+
"@epam/ai-dial-quotations": "1.2.0-dev.201",
|
|
131
|
+
"@epam/ai-dial-react-file-manager": "^0.3.0-dev.16",
|
|
132
|
+
"@epam/ai-dial-scheduled-tasks": "1.2.0-dev.201",
|
|
133
|
+
"@epam/ai-dial-share": "1.2.0-dev.201",
|
|
134
|
+
"@epam/ai-dial-skill-editor": "1.2.0-dev.201",
|
|
135
|
+
"@epam/ai-dial-source-panel": "1.2.0-dev.201",
|
|
136
|
+
"@epam/ai-dial-ui-kit": "^0.15.0-dev.23",
|
|
137
|
+
"@epam/ai-dial-usage-dashboard": "1.2.0-dev.201",
|
|
123
138
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
124
139
|
"@epam/pdf-highlighter-kit": "^0.0.19",
|
|
125
140
|
"@mcp-ui/client": "^7.1.1"
|
|
@@ -131,9 +146,6 @@
|
|
|
131
146
|
"@epam/ai-dial-attachment-input": {
|
|
132
147
|
"optional": true
|
|
133
148
|
},
|
|
134
|
-
"@epam/ai-dial-builder-form": {
|
|
135
|
-
"optional": true
|
|
136
|
-
},
|
|
137
149
|
"@epam/ai-dial-catalog": {
|
|
138
150
|
"optional": true
|
|
139
151
|
},
|
|
@@ -170,6 +182,9 @@
|
|
|
170
182
|
"@epam/ai-dial-ui-kit": {
|
|
171
183
|
"optional": true
|
|
172
184
|
},
|
|
185
|
+
"@epam/ai-dial-usage-dashboard": {
|
|
186
|
+
"optional": true
|
|
187
|
+
},
|
|
173
188
|
"@mcp-ui/client": {
|
|
174
189
|
"optional": true
|
|
175
190
|
},
|
|
@@ -182,7 +197,7 @@
|
|
|
182
197
|
},
|
|
183
198
|
"sideEffects": [
|
|
184
199
|
"./oauth.js",
|
|
185
|
-
"./file-manager.js",
|
|
200
|
+
"./file-manager-canvas.js",
|
|
186
201
|
"./shared/toolset-login-events.js",
|
|
187
202
|
"./files/attachment-canvas.js"
|
|
188
203
|
],
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
//#region src/scheduled-task/scheduled-task-description.ts
|
|
2
|
+
var e = /* @__PURE__ */ function(e) {
|
|
3
|
+
return e.OneTime = "oneTime", e.Hourly = "hourly", e.EveryNMinutes = "everyNMinutes", e.Daily = "daily", e.Weekly = "weekly", e.Monthly = "monthly", e.Custom = "custom", e.Invalid = "invalid", e;
|
|
4
|
+
}({}), t = (e, { timeZone: t = "UTC", referenceDate: n = /* @__PURE__ */ new Date() } = {}) => {
|
|
5
|
+
let r = (e, t = {}) => ({
|
|
6
|
+
kind: e,
|
|
7
|
+
sourceTimezone: "utc",
|
|
8
|
+
...t
|
|
9
|
+
});
|
|
10
|
+
if (e.date && e.cron) return r("invalid");
|
|
11
|
+
if (e.date) {
|
|
12
|
+
let t = new Date(e.date);
|
|
13
|
+
return Number.isNaN(t.getTime()) ? r("invalid") : r("oneTime", { date: t });
|
|
14
|
+
}
|
|
15
|
+
let i = e.cron?.fields;
|
|
16
|
+
if (!i || Object.keys(i).length === 0) return r("invalid");
|
|
17
|
+
let a = () => r("custom", { expression: JSON.stringify(i) }), o = {
|
|
18
|
+
hour: [0, 23],
|
|
19
|
+
minute: [0, 59],
|
|
20
|
+
day: [1, 31],
|
|
21
|
+
day_of_week: [0, 6],
|
|
22
|
+
month: [1, 12],
|
|
23
|
+
second: [0, 59]
|
|
24
|
+
};
|
|
25
|
+
for (let [e, t] of Object.entries(i)) {
|
|
26
|
+
if (t == null) continue;
|
|
27
|
+
if (!t.trim()) return r("invalid");
|
|
28
|
+
let n = o[e];
|
|
29
|
+
if (n && /^-?\d+$/.test(t) && (Number(t) < n[0] || Number(t) > n[1])) return r("invalid");
|
|
30
|
+
if (e === "second" && t !== "0" || ![
|
|
31
|
+
"hour",
|
|
32
|
+
"minute",
|
|
33
|
+
"day",
|
|
34
|
+
"day_of_week"
|
|
35
|
+
].includes(e) && t !== "*" && !(e === "second" && t === "0")) return a();
|
|
36
|
+
}
|
|
37
|
+
let s = i.hour, c = i.minute, l = i.day === "*" ? void 0 : i.day, u = i.day_of_week === "*" ? void 0 : i.day_of_week, d = u ? [
|
|
38
|
+
"monday",
|
|
39
|
+
"tuesday",
|
|
40
|
+
"wednesday",
|
|
41
|
+
"thursday",
|
|
42
|
+
"friday",
|
|
43
|
+
"saturday",
|
|
44
|
+
"sunday"
|
|
45
|
+
].findIndex((e) => e === u.toLowerCase() || e.slice(0, 3) === u.toLowerCase()) : -1, f = d >= 0 ? String(d) : u;
|
|
46
|
+
if (l && f || l && !/^\d+$/.test(l) || f && !/^\d+$/.test(f)) return a();
|
|
47
|
+
let p = s == null || s === "*", m = c?.match(/^\*\/(\d+)$/);
|
|
48
|
+
if (p && m && !l && !f) {
|
|
49
|
+
let e = Number(m[1]);
|
|
50
|
+
return e > 0 && e <= 59 ? r("everyNMinutes", { intervalMinutes: e }) : r("invalid");
|
|
51
|
+
}
|
|
52
|
+
if (!c || !/^\d+$/.test(c) || !p && !/^\d+$/.test(s) || p && (l || f)) return a();
|
|
53
|
+
let h = new Date(n);
|
|
54
|
+
if (Number.isNaN(h.getTime())) return r("invalid");
|
|
55
|
+
if (h.setUTCHours(p ? 0 : Number(s), Number(c), 0, 0), f) {
|
|
56
|
+
let e = (Number(f) + 1) % 7;
|
|
57
|
+
h.setUTCDate(h.getUTCDate() + (e - h.getUTCDay() + 7) % 7);
|
|
58
|
+
}
|
|
59
|
+
let g = new Intl.DateTimeFormat("en-GB", {
|
|
60
|
+
timeZone: t,
|
|
61
|
+
hourCycle: "h23",
|
|
62
|
+
year: "numeric",
|
|
63
|
+
month: "2-digit",
|
|
64
|
+
day: "2-digit",
|
|
65
|
+
hour: "2-digit",
|
|
66
|
+
minute: "2-digit"
|
|
67
|
+
}).formatToParts(h), _ = (e) => g.find((t) => t.type === e)?.value ?? "", v = new Date(Date.UTC(Number(_("year")), Number(_("month")) - 1, Number(_("day")))), y = Date.UTC(h.getUTCFullYear(), h.getUTCMonth(), h.getUTCDate()), b = Math.round((v.getTime() - y) / 864e5), x = _("hour") + ":" + _("minute");
|
|
68
|
+
return p ? r("hourly", { time: _("minute") }) : f ? r("weekly", {
|
|
69
|
+
time: x,
|
|
70
|
+
dayOfWeek: String((Number(f) + b + 7) % 7)
|
|
71
|
+
}) : l ? b === 0 || Number(l) <= 28 && Number(l) + b >= 1 && Number(l) + b <= 28 ? r("monthly", {
|
|
72
|
+
time: x,
|
|
73
|
+
dayOfMonth: String(Number(l) + b)
|
|
74
|
+
}) : a() : r("daily", { time: x });
|
|
75
|
+
};
|
|
76
|
+
//#endregion
|
|
77
|
+
export { e as ScheduledTaskTriggerDescriptionKind, t as describeScheduledTaskTrigger };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { mapFormValuesToCreateBody as e, mapFormValuesToUpdateBody as t } from "./scheduled-task-trigger.js";
|
|
2
|
+
import { validateScheduledTaskFormValues as n } from "@epam/ai-dial-scheduled-tasks/validation";
|
|
3
|
+
//#region src/scheduled-task/scheduled-task-preparation.ts
|
|
4
|
+
var r = (t, r) => {
|
|
5
|
+
let i = n(t, r);
|
|
6
|
+
return Object.keys(i).length > 0 ? {
|
|
7
|
+
ok: !1,
|
|
8
|
+
errors: i
|
|
9
|
+
} : {
|
|
10
|
+
ok: !0,
|
|
11
|
+
body: e(t)
|
|
12
|
+
};
|
|
13
|
+
}, i = (e, r) => {
|
|
14
|
+
let i = n(e, r);
|
|
15
|
+
return Object.keys(i).length > 0 ? {
|
|
16
|
+
ok: !1,
|
|
17
|
+
errors: i
|
|
18
|
+
} : {
|
|
19
|
+
ok: !0,
|
|
20
|
+
body: t(e)
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
//#endregion
|
|
24
|
+
export { r as prepareScheduledTaskCreateBody, i as prepareScheduledTaskUpdateBody };
|
|
@@ -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 {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/scheduled-task/scheduled-tasks-api-client.ts
|
|
2
|
+
var e = (e) => {
|
|
3
|
+
if (!Array.isArray(e.items)) throw TypeError("Scheduled tasks API returned a malformed page response");
|
|
4
|
+
return e;
|
|
5
|
+
}, t = (t) => ({
|
|
6
|
+
listScheduledTasks: async ({ signal: n, ...r } = {}) => e(await t.listScheduledTasks(r, n ? { signal: n } : void 0)),
|
|
7
|
+
listScheduledTaskRuns: async ({ signal: n, ...r }) => e(await t.listScheduledTaskRuns(r, n ? { signal: n } : void 0)),
|
|
8
|
+
createScheduledTask: (e) => t.createScheduledTask({ createScheduledTaskBodyDto: e }),
|
|
9
|
+
getScheduledTask: (e) => t.getScheduledTask({ scheduleId: e }),
|
|
10
|
+
updateScheduledTask: (e, n) => t.updateScheduledTask({
|
|
11
|
+
scheduleId: e,
|
|
12
|
+
updateScheduledTaskBodyDto: n
|
|
13
|
+
}),
|
|
14
|
+
pauseScheduledTask: (e) => t.pauseScheduledTask({ scheduleId: e }),
|
|
15
|
+
resumeScheduledTask: (e) => t.resumeScheduledTask({ scheduleId: e }),
|
|
16
|
+
deleteScheduledTask: (e) => t.deleteScheduledTask({ scheduleId: e })
|
|
17
|
+
});
|
|
18
|
+
//#endregion
|
|
19
|
+
export { t as createScheduledTasksApiClient };
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { useCallback as e, useEffect as t, useRef as n, useState as r } from "react";
|
|
2
|
+
import { ScheduledTaskRunDtoStatusEnum as i } from "@epam/ai-dial-chat-api-client";
|
|
3
|
+
//#region src/scheduled-task/use-scheduled-task-runs.ts
|
|
4
|
+
var a = 15e3, o = 20, s = 5e3, c = 2147483647, l = (e, t) => {
|
|
5
|
+
if (e <= c) {
|
|
6
|
+
let n = setTimeout(t, Math.max(e, 0));
|
|
7
|
+
return () => clearTimeout(n);
|
|
8
|
+
}
|
|
9
|
+
let n, r = setTimeout(() => {
|
|
10
|
+
n = l(e - c, t);
|
|
11
|
+
}, c);
|
|
12
|
+
return n = () => clearTimeout(r), () => n();
|
|
13
|
+
}, u = (e, t) => {
|
|
14
|
+
let n = new Map(t.map((e) => [e.id, e])), r = new Set(e.map((e) => e.id)), i = e.map((e) => n.get(e.id) ?? e);
|
|
15
|
+
return [...t.filter((e) => !r.has(e.id)), ...i];
|
|
16
|
+
}, d = (e, t) => {
|
|
17
|
+
if (e.length !== t.length) return !0;
|
|
18
|
+
let n = new Map(e.map((e) => [e.id, e]));
|
|
19
|
+
return t.some((e) => {
|
|
20
|
+
let t = n.get(e.id);
|
|
21
|
+
return !t || JSON.stringify(t) !== JSON.stringify(e);
|
|
22
|
+
});
|
|
23
|
+
}, f = (c, { scheduleId: f, enabled: p = !0, pageSize: m = 10, nextRunTime: h }) => {
|
|
24
|
+
let [g, _] = r([]), [v, y] = r(p), [b, x] = r(!1), [S, C] = r(null), [w, T] = r(null), [E, D] = r(!1), [O, k] = r(0), A = n(0), j = n(0), M = n(!1), N = n(null), P = n(g), F = n(v), I = n(b), L = n(null), R = n(0), z = n(null), B = n(!1);
|
|
25
|
+
P.current = g, F.current = v, I.current = b;
|
|
26
|
+
let V = g.some((e) => e.status === i.InProgress);
|
|
27
|
+
t(() => {
|
|
28
|
+
let e = ++A.current, t = new AbortController();
|
|
29
|
+
N.current?.abort(), N.current = null, L.current?.abort(), L.current = null, M.current = !1, R.current = 0, z.current = null, B.current = !1, x(!1), C(null), T(null), _([]), D(!1), j.current = 0;
|
|
30
|
+
let n = () => {
|
|
31
|
+
++A.current, t.abort(), N.current?.abort(), N.current = null, L.current?.abort(), L.current = null;
|
|
32
|
+
};
|
|
33
|
+
return !p || !f ? (y(!1), _([]), D(!1), n) : ((async () => {
|
|
34
|
+
y(!0);
|
|
35
|
+
try {
|
|
36
|
+
let n = await c.listScheduledTaskRuns({
|
|
37
|
+
scheduleId: f,
|
|
38
|
+
limit: m,
|
|
39
|
+
offset: 0,
|
|
40
|
+
signal: t.signal
|
|
41
|
+
});
|
|
42
|
+
if (A.current !== e) return;
|
|
43
|
+
_(n.items), j.current = n.items.length, D(n.next != null || (n.count == null ? n.items.length === m : n.items.length < n.count));
|
|
44
|
+
} catch (t) {
|
|
45
|
+
A.current === e && C(t instanceof Error ? t : /* @__PURE__ */ Error("Failed to load scheduled task runs"));
|
|
46
|
+
} finally {
|
|
47
|
+
A.current === e && y(!1);
|
|
48
|
+
}
|
|
49
|
+
})(), n);
|
|
50
|
+
}, [
|
|
51
|
+
c,
|
|
52
|
+
p,
|
|
53
|
+
m,
|
|
54
|
+
O,
|
|
55
|
+
f
|
|
56
|
+
]);
|
|
57
|
+
let H = e(() => {
|
|
58
|
+
if (!p || !f || !E || v || M.current) return;
|
|
59
|
+
M.current = !0;
|
|
60
|
+
let e = new AbortController();
|
|
61
|
+
N.current = e;
|
|
62
|
+
let t = A.current, n = j.current;
|
|
63
|
+
(async () => {
|
|
64
|
+
x(!0), T(null);
|
|
65
|
+
try {
|
|
66
|
+
let r = await c.listScheduledTaskRuns({
|
|
67
|
+
scheduleId: f,
|
|
68
|
+
limit: m,
|
|
69
|
+
offset: n,
|
|
70
|
+
signal: e.signal
|
|
71
|
+
});
|
|
72
|
+
if (A.current !== t) return;
|
|
73
|
+
_((e) => {
|
|
74
|
+
let t = new Set(e.map(({ id: e }) => e));
|
|
75
|
+
return [...e, ...r.items.filter(({ id: e }) => t.has(e) ? !1 : (t.add(e), !0))];
|
|
76
|
+
}), j.current = n + r.items.length, D(r.next != null || (r.count == null ? r.items.length === m : n + r.items.length < r.count));
|
|
77
|
+
} catch (e) {
|
|
78
|
+
A.current === t && T(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to load more scheduled task runs"));
|
|
79
|
+
} finally {
|
|
80
|
+
A.current === t && (x(!1), M.current = !1, N.current = null);
|
|
81
|
+
}
|
|
82
|
+
})();
|
|
83
|
+
}, [
|
|
84
|
+
c,
|
|
85
|
+
p,
|
|
86
|
+
E,
|
|
87
|
+
v,
|
|
88
|
+
m,
|
|
89
|
+
f
|
|
90
|
+
]), U = e(async () => {
|
|
91
|
+
if (F.current || I.current) return "skipped";
|
|
92
|
+
let e = A.current, t = new AbortController();
|
|
93
|
+
L.current?.abort(), L.current = t;
|
|
94
|
+
try {
|
|
95
|
+
let n = await c.listScheduledTaskRuns({
|
|
96
|
+
scheduleId: f,
|
|
97
|
+
limit: m,
|
|
98
|
+
offset: 0,
|
|
99
|
+
signal: t.signal
|
|
100
|
+
});
|
|
101
|
+
if (A.current !== e || F.current || I.current) return "skipped";
|
|
102
|
+
let r = P.current, i = u(r, n.items), a = d(r, i);
|
|
103
|
+
return a && (P.current = i, _(i)), a ? "changed" : "unchanged";
|
|
104
|
+
} catch {
|
|
105
|
+
return "error";
|
|
106
|
+
} finally {
|
|
107
|
+
L.current === t && (L.current = null);
|
|
108
|
+
}
|
|
109
|
+
}, [
|
|
110
|
+
c,
|
|
111
|
+
f,
|
|
112
|
+
m
|
|
113
|
+
]), W = e(() => {
|
|
114
|
+
if (document.visibilityState !== "visible") {
|
|
115
|
+
B.current = !0;
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
U();
|
|
119
|
+
}, [U]);
|
|
120
|
+
return t(() => {
|
|
121
|
+
if (!p || !f || !V) return;
|
|
122
|
+
R.current = 0;
|
|
123
|
+
let e = setInterval(() => {
|
|
124
|
+
if (document.visibilityState !== "visible") {
|
|
125
|
+
B.current = !0;
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
(async () => {
|
|
129
|
+
let t = await U();
|
|
130
|
+
if (t === "changed") {
|
|
131
|
+
R.current = 0;
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
(t === "unchanged" || t === "error") && (R.current += 1, R.current >= o && e !== null && (clearInterval(e), e = null));
|
|
135
|
+
})();
|
|
136
|
+
}, a);
|
|
137
|
+
return () => {
|
|
138
|
+
e !== null && clearInterval(e);
|
|
139
|
+
};
|
|
140
|
+
}, [
|
|
141
|
+
p,
|
|
142
|
+
f,
|
|
143
|
+
V,
|
|
144
|
+
U
|
|
145
|
+
]), t(() => {
|
|
146
|
+
if (!p || !f || !h) return;
|
|
147
|
+
let e = new Date(h).getTime();
|
|
148
|
+
if (!(Number.isNaN(e) || e <= Date.now())) return l(e - Date.now() + s, () => {
|
|
149
|
+
z.current = h, W();
|
|
150
|
+
});
|
|
151
|
+
}, [
|
|
152
|
+
p,
|
|
153
|
+
f,
|
|
154
|
+
h,
|
|
155
|
+
W
|
|
156
|
+
]), t(() => {
|
|
157
|
+
if (!p || !f) return;
|
|
158
|
+
let e = () => {
|
|
159
|
+
document.visibilityState !== "visible" || !B.current || (async () => {
|
|
160
|
+
await U() !== "skipped" && (B.current = !1);
|
|
161
|
+
})();
|
|
162
|
+
};
|
|
163
|
+
return document.addEventListener("visibilitychange", e), () => {
|
|
164
|
+
document.removeEventListener("visibilitychange", e);
|
|
165
|
+
};
|
|
166
|
+
}, [
|
|
167
|
+
p,
|
|
168
|
+
f,
|
|
169
|
+
U
|
|
170
|
+
]), t(() => {
|
|
171
|
+
if (!p || !f || !h || v || b) return;
|
|
172
|
+
let e = new Date(h).getTime();
|
|
173
|
+
Number.isNaN(e) || e > Date.now() || z.current !== h && (z.current = h, W());
|
|
174
|
+
}, [
|
|
175
|
+
p,
|
|
176
|
+
f,
|
|
177
|
+
h,
|
|
178
|
+
v,
|
|
179
|
+
b,
|
|
180
|
+
W
|
|
181
|
+
]), {
|
|
182
|
+
items: g,
|
|
183
|
+
isLoading: v,
|
|
184
|
+
isLoadingMore: b,
|
|
185
|
+
initialError: S,
|
|
186
|
+
loadMoreError: w,
|
|
187
|
+
hasMore: E,
|
|
188
|
+
loadMore: H,
|
|
189
|
+
retryLoadMore: H,
|
|
190
|
+
refetch: e(() => k((e) => e + 1), [])
|
|
191
|
+
};
|
|
192
|
+
};
|
|
193
|
+
//#endregion
|
|
194
|
+
export { u as mergeRunsById, f as useScheduledTaskRuns };
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { useCallback as e, useEffect as t, useRef as n, useState as r } from "react";
|
|
2
|
+
//#region src/scheduled-task/use-scheduled-tasks.ts
|
|
3
|
+
var i = (i, { enabled: a = !0, pageSize: o = 20, debounceMs: s = 300, initialSearch: c = "", initialSort: l = "first_to_run" } = {}) => {
|
|
4
|
+
let [u, d] = r([]), [f, p] = r(c), [m, h] = r(l), [g, _] = r(a), [v, y] = r(!1), [b, x] = r(null), [S, C] = r(null), [w, T] = r(!1), [E, D] = r(0), O = n(0), k = n(0), A = n(!1), j = n(null), [M, N] = r(c);
|
|
5
|
+
t(() => {
|
|
6
|
+
let e = setTimeout(() => N(f), s);
|
|
7
|
+
return () => clearTimeout(e);
|
|
8
|
+
}, [s, f]), t(() => {
|
|
9
|
+
let e = ++O.current, t = new AbortController();
|
|
10
|
+
j.current?.abort(), j.current = null, A.current = !1, y(!1), x(null), C(null), d([]), T(!1), k.current = 0;
|
|
11
|
+
let n = () => {
|
|
12
|
+
++O.current, t.abort(), j.current?.abort(), j.current = null;
|
|
13
|
+
};
|
|
14
|
+
return a ? ((async () => {
|
|
15
|
+
_(!0);
|
|
16
|
+
try {
|
|
17
|
+
let n = await i.listScheduledTasks({
|
|
18
|
+
limit: o,
|
|
19
|
+
offset: 0,
|
|
20
|
+
search: M,
|
|
21
|
+
sort: m,
|
|
22
|
+
signal: t.signal
|
|
23
|
+
});
|
|
24
|
+
if (O.current !== e) return;
|
|
25
|
+
d(n.items), k.current = n.items.length, T(n.next != null);
|
|
26
|
+
} catch (t) {
|
|
27
|
+
O.current === e && x(t instanceof Error ? t : /* @__PURE__ */ Error("Failed to load scheduled tasks"));
|
|
28
|
+
} finally {
|
|
29
|
+
O.current === e && _(!1);
|
|
30
|
+
}
|
|
31
|
+
})(), n) : (_(!1), d([]), T(!1), n);
|
|
32
|
+
}, [
|
|
33
|
+
i,
|
|
34
|
+
M,
|
|
35
|
+
a,
|
|
36
|
+
o,
|
|
37
|
+
E,
|
|
38
|
+
m
|
|
39
|
+
]);
|
|
40
|
+
let P = e(() => {
|
|
41
|
+
if (!a || !w || g || A.current) return;
|
|
42
|
+
A.current = !0;
|
|
43
|
+
let e = new AbortController();
|
|
44
|
+
j.current = e;
|
|
45
|
+
let t = O.current, n = k.current;
|
|
46
|
+
(async () => {
|
|
47
|
+
y(!0), C(null);
|
|
48
|
+
try {
|
|
49
|
+
let r = await i.listScheduledTasks({
|
|
50
|
+
limit: o,
|
|
51
|
+
offset: n,
|
|
52
|
+
signal: e.signal,
|
|
53
|
+
search: M,
|
|
54
|
+
sort: m
|
|
55
|
+
});
|
|
56
|
+
if (O.current !== t) return;
|
|
57
|
+
d((e) => {
|
|
58
|
+
let t = new Set(e.map(({ id: e }) => e));
|
|
59
|
+
return [...e, ...r.items.filter(({ id: e }) => t.has(e) ? !1 : (t.add(e), !0))];
|
|
60
|
+
}), k.current = n + r.items.length, T(r.next != null);
|
|
61
|
+
} catch (e) {
|
|
62
|
+
O.current === t && C(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to load more scheduled tasks"));
|
|
63
|
+
} finally {
|
|
64
|
+
O.current === t && (y(!1), A.current = !1, j.current = null);
|
|
65
|
+
}
|
|
66
|
+
})();
|
|
67
|
+
}, [
|
|
68
|
+
i,
|
|
69
|
+
M,
|
|
70
|
+
a,
|
|
71
|
+
w,
|
|
72
|
+
g,
|
|
73
|
+
o,
|
|
74
|
+
m
|
|
75
|
+
]);
|
|
76
|
+
return {
|
|
77
|
+
items: u,
|
|
78
|
+
searchQuery: f,
|
|
79
|
+
setSearchQuery: p,
|
|
80
|
+
sortKey: m,
|
|
81
|
+
setSortKey: h,
|
|
82
|
+
isLoading: g,
|
|
83
|
+
isLoadingMore: v,
|
|
84
|
+
initialError: b,
|
|
85
|
+
loadMoreError: S,
|
|
86
|
+
hasMore: w,
|
|
87
|
+
loadMore: P,
|
|
88
|
+
retryLoadMore: P,
|
|
89
|
+
refetch: e(() => D((e) => e + 1), [])
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
//#endregion
|
|
93
|
+
export { i as useScheduledTasks };
|