@stack-spot/ai-chat-widget 2.9.0 → 2.11.0
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/CHANGELOG.md +15 -0
- package/dist/app-metadata.json +3 -3
- package/dist/chat-interceptors/quick-commands.d.ts.map +1 -1
- package/dist/chat-interceptors/quick-commands.js +14 -5
- package/dist/chat-interceptors/quick-commands.js.map +1 -1
- package/dist/components/Selector/index.d.ts +11 -2
- package/dist/components/Selector/index.d.ts.map +1 -1
- package/dist/components/Selector/index.js +18 -17
- package/dist/components/Selector/index.js.map +1 -1
- package/dist/components/form/DescribedCheckboxGroup.d.ts +3 -1
- package/dist/components/form/DescribedCheckboxGroup.d.ts.map +1 -1
- package/dist/components/form/DescribedCheckboxGroup.js +31 -19
- package/dist/components/form/DescribedCheckboxGroup.js.map +1 -1
- package/dist/views/Agents/AgentsTab.js.map +1 -1
- package/dist/views/KnowledgeSources.d.ts.map +1 -1
- package/dist/views/KnowledgeSources.js +31 -17
- package/dist/views/KnowledgeSources.js.map +1 -1
- package/dist/views/MessageInput/AgentSelector.d.ts.map +1 -1
- package/dist/views/MessageInput/AgentSelector.js +8 -6
- package/dist/views/MessageInput/AgentSelector.js.map +1 -1
- package/dist/views/MessageInput/QuickCommandSelector.d.ts.map +1 -1
- package/dist/views/MessageInput/QuickCommandSelector.js +12 -8
- package/dist/views/MessageInput/QuickCommandSelector.js.map +1 -1
- package/package.json +2 -2
- package/src/app-metadata.json +3 -3
- package/src/chat-interceptors/quick-commands.ts +14 -5
- package/src/components/Selector/index.tsx +46 -33
- package/src/components/form/DescribedCheckboxGroup.tsx +61 -35
- package/src/views/Agents/AgentsTab.tsx +5 -5
- package/src/views/KnowledgeSources.tsx +59 -36
- package/src/views/MessageInput/AgentSelector.tsx +10 -8
- package/src/views/MessageInput/QuickCommandSelector.tsx +33 -23
|
@@ -2,6 +2,7 @@ import { Button, Tab } from '@stack-spot/citric-react'
|
|
|
2
2
|
import { Placeholder } from '@stack-spot/portal-components/Placeholder'
|
|
3
3
|
import { aiClient, dataIntegrationClient, workspaceAiClient } from '@stack-spot/portal-network'
|
|
4
4
|
import { VisibilityLevelEnum } from '@stack-spot/portal-network/api/ai'
|
|
5
|
+
import { KnowledgeSourceItemResponse } from '@stack-spot/portal-network/api/dataIntegration'
|
|
5
6
|
import { WorkspaceResponse } from '@stack-spot/portal-network/api/workspace-ai'
|
|
6
7
|
import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
|
|
7
8
|
import React, { useCallback, useEffect, useMemo, useRef } from 'react'
|
|
@@ -64,13 +65,19 @@ const KnowledgeSourcesPanel = () => {
|
|
|
64
65
|
}, [chat])
|
|
65
66
|
|
|
66
67
|
const allTabsMap: Partial<Record<Scope, Omit<Tab, 'key'>>> = {
|
|
67
|
-
favorite: {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
favorite: {
|
|
69
|
+
label: t.favorites,
|
|
70
|
+
content: <KnowledgeSourcesTab key="favorite" visibility="favorite" allKS={allKS} onSubmit={onSubmit} />,
|
|
71
|
+
},
|
|
72
|
+
personal: {
|
|
73
|
+
label: t.personal,
|
|
74
|
+
content: <KnowledgeSourcesTab key="personal" visibility="personal" allKS={allKS} onSubmit={onSubmit} />,
|
|
75
|
+
},
|
|
71
76
|
shared: { label: t.shared, content: <KnowledgeSourcesTab key="shared" visibility="shared" allKS={allKS} onSubmit={onSubmit} /> },
|
|
72
|
-
workspace: {
|
|
73
|
-
|
|
77
|
+
workspace: {
|
|
78
|
+
label: t.spots,
|
|
79
|
+
content: <KnowledgeSourcesTabWorkspace key="workspace" visibility="workspace" allKS={allKS} onSubmit={onSubmit} />,
|
|
80
|
+
},
|
|
74
81
|
account: { label: t.account, content: <KnowledgeSourcesTab key="account" visibility="account" allKS={allKS} onSubmit={onSubmit} /> },
|
|
75
82
|
}
|
|
76
83
|
|
|
@@ -95,16 +102,29 @@ const KnowledgeSourcesPanel = () => {
|
|
|
95
102
|
|
|
96
103
|
export const KnowledgeSourcesTab = ({ visibility, allKS, onSubmit, workspaceId, showSubmitButton = true }: TabProps) => {
|
|
97
104
|
const t = useTranslate(dictionary)
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
105
|
+
const [data = []] = workspaceAiClient.getKSFromWorkspaceAi.useStatefulQuery(
|
|
106
|
+
{ workspaceId: workspaceId! }, { enabled: !!workspaceId })
|
|
107
|
+
const workspaceKs = data as KnowledgeSourceItemResponse[]
|
|
108
|
+
|
|
109
|
+
const [ksListPages = [], { fetchNextPage, hasNextPage }] = dataIntegrationClient.knowledgeSourcesV2.useInfiniteQuery(
|
|
110
|
+
{
|
|
111
|
+
order: 'a-to-z',
|
|
112
|
+
visibilityList: visibility ? [visibility] : [],
|
|
113
|
+
types: ['snippet', 'api', 'event', 'custom'],
|
|
114
|
+
size: 20,
|
|
115
|
+
page: 1,
|
|
116
|
+
},
|
|
117
|
+
{ enabled: !workspaceId },
|
|
118
|
+
)
|
|
119
|
+
const knowledgeSources = workspaceId ? workspaceKs : ksListPages
|
|
120
|
+
|
|
103
121
|
const initialValue = useMemo(() => {
|
|
104
122
|
const currentlySelected = allKS.current?.map(ks => ks.id)
|
|
105
|
-
return knowledgeSources
|
|
106
|
-
}, [])
|
|
107
|
-
|
|
123
|
+
return knowledgeSources?.filter((ks: KnowledgeSourceItemResponse) => currentlySelected?.includes(ks.slug))
|
|
124
|
+
}, [knowledgeSources])
|
|
125
|
+
|
|
126
|
+
const listFavorites = dataIntegrationClient.knowledgeSourcesV2.useQuery({ visibilityList: ['favorite'] })?.items
|
|
127
|
+
|
|
108
128
|
const [addFavorite, pendingAddFav] = dataIntegrationClient.addFavoriteKnowledgeSource.useMutation()
|
|
109
129
|
const [removeFavorite, pendingRemoveFav] = dataIntegrationClient.removeFavoriteKnowledgeSource.useMutation()
|
|
110
130
|
|
|
@@ -112,7 +132,7 @@ export const KnowledgeSourcesTab = ({ visibility, allKS, onSubmit, workspaceId,
|
|
|
112
132
|
try {
|
|
113
133
|
await removeFavorite({ slug: idOrSlug })
|
|
114
134
|
await aiClient.knowledgeSources.invalidate()
|
|
115
|
-
await dataIntegrationClient.
|
|
135
|
+
await dataIntegrationClient.knowledgeSourcesV2.invalidate()
|
|
116
136
|
} catch (error) {
|
|
117
137
|
// eslint-disable-next-line no-console
|
|
118
138
|
console.error(error)
|
|
@@ -123,7 +143,7 @@ export const KnowledgeSourcesTab = ({ visibility, allKS, onSubmit, workspaceId,
|
|
|
123
143
|
const onRemoveFavorite = (idOrSlug: string) => new Promise<boolean>(async (resolve, reject) => {
|
|
124
144
|
try {
|
|
125
145
|
await removeFavoriteKs(idOrSlug)
|
|
126
|
-
if (!pendingRemoveFav){
|
|
146
|
+
if (!pendingRemoveFav) {
|
|
127
147
|
resolve(true)
|
|
128
148
|
}
|
|
129
149
|
|
|
@@ -131,14 +151,14 @@ export const KnowledgeSourcesTab = ({ visibility, allKS, onSubmit, workspaceId,
|
|
|
131
151
|
// eslint-disable-next-line no-console
|
|
132
152
|
console.error(error)
|
|
133
153
|
reject(error)
|
|
134
|
-
}
|
|
154
|
+
}
|
|
135
155
|
})
|
|
136
156
|
|
|
137
157
|
const addFavoriteKs = async (idOrSlug: string) => {
|
|
138
158
|
try {
|
|
139
159
|
await addFavorite({ slug: idOrSlug })
|
|
140
160
|
await aiClient.knowledgeSources.invalidate()
|
|
141
|
-
await dataIntegrationClient.
|
|
161
|
+
await dataIntegrationClient.knowledgeSourcesV2.invalidate()
|
|
142
162
|
} catch (error) {
|
|
143
163
|
// eslint-disable-next-line no-console
|
|
144
164
|
console.error(error)
|
|
@@ -149,7 +169,7 @@ export const KnowledgeSourcesTab = ({ visibility, allKS, onSubmit, workspaceId,
|
|
|
149
169
|
const onAddFavorite = (idOrSlug: string) => new Promise<boolean>(async (resolve, reject) => {
|
|
150
170
|
try {
|
|
151
171
|
await addFavoriteKs(idOrSlug)
|
|
152
|
-
if (!pendingAddFav){
|
|
172
|
+
if (!pendingAddFav) {
|
|
153
173
|
resolve(true)
|
|
154
174
|
}
|
|
155
175
|
|
|
@@ -157,23 +177,27 @@ export const KnowledgeSourcesTab = ({ visibility, allKS, onSubmit, workspaceId,
|
|
|
157
177
|
// eslint-disable-next-line no-console
|
|
158
178
|
console.error(error)
|
|
159
179
|
reject(error)
|
|
160
|
-
}
|
|
180
|
+
}
|
|
161
181
|
})
|
|
162
182
|
|
|
163
|
-
return (
|
|
164
|
-
|
|
165
|
-
<
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
183
|
+
return (<>
|
|
184
|
+
<div className="content">
|
|
185
|
+
<DescribedCheckboxGroup
|
|
186
|
+
options={knowledgeSources}
|
|
187
|
+
initialValue={initialValue}
|
|
188
|
+
globalSelection={allKS}
|
|
189
|
+
hasNextPage={hasNextPage && !workspaceId}
|
|
190
|
+
fetchNextPage={fetchNextPage}
|
|
191
|
+
data={(ks: KnowledgeSourceItemResponse) => ({
|
|
192
|
+
idOrSlug: ks.slug, description: ks.description, name: ks.name, listFavorites,
|
|
193
|
+
onAddFavorite, onRemoveFavorite,
|
|
194
|
+
})}
|
|
195
|
+
emptyResults={<Placeholder title={t.noSearchResults} description={t.noSearchResultsDescription} />}
|
|
196
|
+
emptyDataset={<Placeholder title={t.noData} description={t.noDataDescription} className="no-data-placeholder" />}
|
|
197
|
+
/>
|
|
198
|
+
</div>
|
|
199
|
+
{!!knowledgeSources?.length && showSubmitButton && <Button onClick={onSubmit}>{t.apply}</Button>}
|
|
200
|
+
</>
|
|
177
201
|
)
|
|
178
202
|
}
|
|
179
203
|
|
|
@@ -184,11 +208,10 @@ export function KnowledgeSourcesTabWorkspace({ allKS, onSubmit }: TabProps) {
|
|
|
184
208
|
component: 'ks',
|
|
185
209
|
props: { visibility: 'workspace', workspaceId: workspace.id, allKS, onSubmit },
|
|
186
210
|
})
|
|
187
|
-
|
|
211
|
+
|
|
188
212
|
return <WorkspaceTabNavigator components={workspaceTabComponents} getNavigateParam={buildNavigateParams} />
|
|
189
213
|
}
|
|
190
214
|
|
|
191
|
-
|
|
192
215
|
const dictionary = {
|
|
193
216
|
en: {
|
|
194
217
|
title: 'Knowledge Sources',
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Icon } from '@stack-spot/citric-icons'
|
|
2
2
|
import { IconBox, Row, Text } from '@stack-spot/citric-react'
|
|
3
|
-
import { AgentResponseWithBuiltIn, agentToolsClient, workspaceAiClient } from '@stack-spot/portal-network'
|
|
3
|
+
import { AgentResponseWithBuiltIn, agentToolsClient, AgentVisibilityLevel, workspaceAiClient } from '@stack-spot/portal-network'
|
|
4
|
+
import { VisibilityLevelEnum } from '@stack-spot/portal-network/api/agent-tools'
|
|
4
5
|
import { useCallback } from 'react'
|
|
5
6
|
import { Selector } from '../../components/Selector'
|
|
6
7
|
import { useCurrentChat, useCurrentChatState, useWidgetState } from '../../context/hooks'
|
|
@@ -54,18 +55,19 @@ export const AgentSelector = ({ inputRef, isTrial }: {
|
|
|
54
55
|
}, [chat, inputRef])
|
|
55
56
|
|
|
56
57
|
|
|
57
|
-
const getAgents = () => {
|
|
58
|
+
const getAgents = ({ filter, visibility }: {filter?: string, visibility?: AgentVisibilityLevel[] | VisibilityLevelEnum[]}) => {
|
|
58
59
|
if (spotId) {
|
|
59
|
-
return workspaceAiClient.getAgentFromWorkspaceAi.useQuery({
|
|
60
|
+
return { data: workspaceAiClient.getAgentFromWorkspaceAi.useQuery({
|
|
61
|
+
workspaceId: spotId, name: filter }) as AgentResponseWithBuiltIn[] }
|
|
60
62
|
}
|
|
61
63
|
|
|
62
64
|
if (isTrial) {
|
|
63
|
-
return agentToolsClient.allAgents.useQuery({ visibilities: [
|
|
65
|
+
return { data: agentToolsClient.allAgents.useQuery({ visibilities: visibility as VisibilityLevelEnum[], filter }) }
|
|
64
66
|
}
|
|
65
|
-
|
|
66
|
-
return agentToolsClient.allAgents.useQuery({
|
|
67
|
-
visibilities:
|
|
68
|
-
})
|
|
67
|
+
|
|
68
|
+
return { data: agentToolsClient.allAgents.useQuery({
|
|
69
|
+
visibilities: visibility as VisibilityLevelEnum[], filter,
|
|
70
|
+
}) }
|
|
69
71
|
}
|
|
70
72
|
|
|
71
73
|
return <Selector
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Icon } from '@stack-spot/citric-icons'
|
|
2
|
-
import { aiClient, workspaceAiClient } from '@stack-spot/portal-network'
|
|
3
|
-
import { QuickCommandResponse } from '@stack-spot/portal-network/api/ai'
|
|
2
|
+
import { AgentVisibilityLevel, aiClient, workspaceAiClient } from '@stack-spot/portal-network'
|
|
3
|
+
import { QuickCommandResponse, VisibilityLevelEnum } from '@stack-spot/portal-network/api/ai'
|
|
4
4
|
import { useCallback } from 'react'
|
|
5
5
|
import { Selector } from '../../components/Selector'
|
|
6
6
|
import { useCurrentChat, useCurrentChatState, useWidgetState } from '../../context/hooks'
|
|
@@ -8,17 +8,16 @@ import { quickCommandRegex } from '../../regex'
|
|
|
8
8
|
|
|
9
9
|
type QuickCommandResponseWithSpaceName = QuickCommandResponse & { spaceName?: string }
|
|
10
10
|
|
|
11
|
-
export const QuickCommandSelector = ({ inputRef, isTrial }:
|
|
11
|
+
export const QuickCommandSelector = ({ inputRef, isTrial }:
|
|
12
12
|
{ isTrial: boolean, inputRef: React.RefObject<HTMLTextAreaElement | HTMLInputElement> }) => {
|
|
13
13
|
const chat = useCurrentChat()
|
|
14
|
-
const isQuickCommandEnabled =
|
|
14
|
+
const isQuickCommandEnabled = useCurrentChatState('features').quickCommands
|
|
15
15
|
const spotId = useWidgetState('features')?.workspaceId
|
|
16
16
|
|
|
17
|
-
const useFavorites = () => aiClient.allQuickCommands.useQuery({ visibility: 'favorite' })
|
|
18
17
|
const [addFavorite, pendingAddFav] = aiClient.addFavoriteQuickCommand.useMutation()
|
|
19
18
|
const [removeFavorite, pendingRemoveFav] = aiClient.removeFavoriteQuickCommand.useMutation()
|
|
20
19
|
|
|
21
|
-
const addFavoriteQc = async(idOrSlug?: string) => {
|
|
20
|
+
const addFavoriteQc = async (idOrSlug?: string) => {
|
|
22
21
|
try {
|
|
23
22
|
await addFavorite({ slug: idOrSlug || '' })
|
|
24
23
|
await aiClient.allQuickCommands.invalidate()
|
|
@@ -32,7 +31,7 @@ export const QuickCommandSelector = ({ inputRef, isTrial }:
|
|
|
32
31
|
const onAddFavorite = (idOrSlug?: string) => new Promise<boolean>(async (resolve, reject) => {
|
|
33
32
|
try {
|
|
34
33
|
await addFavoriteQc(idOrSlug)
|
|
35
|
-
if (!pendingAddFav){
|
|
34
|
+
if (!pendingAddFav) {
|
|
36
35
|
resolve(true)
|
|
37
36
|
}
|
|
38
37
|
|
|
@@ -40,10 +39,10 @@ export const QuickCommandSelector = ({ inputRef, isTrial }:
|
|
|
40
39
|
// eslint-disable-next-line no-console
|
|
41
40
|
console.error(error)
|
|
42
41
|
reject(error)
|
|
43
|
-
}
|
|
44
|
-
})
|
|
42
|
+
}
|
|
43
|
+
})
|
|
45
44
|
|
|
46
|
-
const removeFavoriteQc = async(idOrSlug?: string) => {
|
|
45
|
+
const removeFavoriteQc = async (idOrSlug?: string) => {
|
|
47
46
|
try {
|
|
48
47
|
await removeFavorite({ slug: idOrSlug || '' })
|
|
49
48
|
await aiClient.allQuickCommands.invalidate()
|
|
@@ -57,7 +56,7 @@ export const QuickCommandSelector = ({ inputRef, isTrial }:
|
|
|
57
56
|
const onRemoveFavorite = (idOrSlug?: string) => new Promise<boolean>(async (resolve, reject) => {
|
|
58
57
|
try {
|
|
59
58
|
await removeFavoriteQc(idOrSlug)
|
|
60
|
-
if (!pendingRemoveFav){
|
|
59
|
+
if (!pendingRemoveFav) {
|
|
61
60
|
resolve(true)
|
|
62
61
|
}
|
|
63
62
|
|
|
@@ -65,9 +64,9 @@ export const QuickCommandSelector = ({ inputRef, isTrial }:
|
|
|
65
64
|
// eslint-disable-next-line no-console
|
|
66
65
|
console.error(error)
|
|
67
66
|
reject(error)
|
|
68
|
-
}
|
|
67
|
+
}
|
|
69
68
|
})
|
|
70
|
-
|
|
69
|
+
|
|
71
70
|
const onSelectItem = useCallback((qc: QuickCommandResponseWithSpaceName) => {
|
|
72
71
|
const newValue = `/${qc.slug}`
|
|
73
72
|
chat.set('nextMessage', newValue)
|
|
@@ -77,12 +76,19 @@ export const QuickCommandSelector = ({ inputRef, isTrial }:
|
|
|
77
76
|
inputRef.current.focus()
|
|
78
77
|
}, [chat, inputRef])
|
|
79
78
|
|
|
80
|
-
const getQuickCommands = () => {
|
|
79
|
+
const getQuickCommands = ({ filter, visibility }: { filter?: string, visibility?: AgentVisibilityLevel[] | VisibilityLevelEnum[] }) => {
|
|
80
|
+
|
|
81
81
|
if (spotId) {
|
|
82
|
-
return workspaceAiClient.getQCFromWorkspaceAi.useQuery({ workspaceId: spotId })
|
|
82
|
+
return { data: workspaceAiClient.getQCFromWorkspaceAi.useQuery({ workspaceId: spotId, name: filter }) }
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
const quickCommands = aiClient.
|
|
85
|
+
const [quickCommands, { fetchNextPage, hasNextPage }] = aiClient.allQuickCommandsV3.useInfiniteQuery({
|
|
86
|
+
order: 'a-to-z',
|
|
87
|
+
visibilityList: visibility as VisibilityLevelEnum[],
|
|
88
|
+
name: filter,
|
|
89
|
+
page: 1, size: 20,
|
|
90
|
+
})
|
|
91
|
+
|
|
86
92
|
const quickCommandsFiltered = quickCommands.filter(
|
|
87
93
|
(qc) => qc.visibility_level.toLowerCase() !== 'workspace',
|
|
88
94
|
)
|
|
@@ -92,11 +98,17 @@ export const QuickCommandSelector = ({ inputRef, isTrial }:
|
|
|
92
98
|
})
|
|
93
99
|
|
|
94
100
|
const workspaceQuickCommandsWithWorkspaceName: QuickCommandResponseWithSpaceName[] =
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
101
|
+
workspaceQuickCommands.flatMap(({ qcs, space_name }) =>
|
|
102
|
+
qcs?.map((qc) => ({ ...qc, spaceName: space_name })),
|
|
103
|
+
) as QuickCommandResponseWithSpaceName[]
|
|
104
|
+
|
|
105
|
+
const filteredWorkspaceQuickCommand = filter ? workspaceQuickCommandsWithWorkspaceName?.filter((qc) =>
|
|
106
|
+
qc.name?.toLowerCase().includes(filter!)) : workspaceQuickCommandsWithWorkspaceName
|
|
98
107
|
|
|
99
|
-
|
|
108
|
+
const data = !visibility ? [...quickCommandsFiltered, ...filteredWorkspaceQuickCommand] : (
|
|
109
|
+
visibility.includes('workspace') ? filteredWorkspaceQuickCommand : quickCommandsFiltered
|
|
110
|
+
)
|
|
111
|
+
return { data, fetchNextPage: fetchNextPage, hasNextPage }
|
|
100
112
|
}
|
|
101
113
|
|
|
102
114
|
const QuickCommandItem = ({ slug, description, spaceName }: QuickCommandResponseWithSpaceName) => <>
|
|
@@ -107,9 +119,7 @@ export const QuickCommandSelector = ({ inputRef, isTrial }:
|
|
|
107
119
|
|
|
108
120
|
return <Selector
|
|
109
121
|
inputRef={inputRef}
|
|
110
|
-
favorite={{
|
|
111
|
-
useFavorites, onAddFavorite, onRemoveFavorite, favoriteIsSlug: true,
|
|
112
|
-
}}
|
|
122
|
+
favorite={{ onAddFavorite, onRemoveFavorite, favoriteIsSlug: true }}
|
|
113
123
|
selectorConfig={{
|
|
114
124
|
resourceName: 'Quick Command',
|
|
115
125
|
shortcut: '/',
|