@stack-spot/ai-chat-widget 3.4.1-beta.5 → 3.6.0-beta.5
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 +89 -6
- package/dist/app-metadata.json +4 -4
- package/dist/chat-interceptors/quick-commands.js +2 -2
- package/dist/chat-interceptors/quick-commands.js.map +1 -1
- package/dist/chat-interceptors/send-message.d.ts.map +1 -1
- package/dist/chat-interceptors/send-message.js +8 -17
- package/dist/chat-interceptors/send-message.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/context/hooks.d.ts +1 -0
- package/dist/context/hooks.d.ts.map +1 -1
- package/dist/context/hooks.js +24 -0
- package/dist/context/hooks.js.map +1 -1
- package/dist/state/ChatEntry.d.ts +8 -0
- package/dist/state/ChatEntry.d.ts.map +1 -1
- package/dist/state/ChatEntry.js +1 -1
- package/dist/state/ChatEntry.js.map +1 -1
- package/dist/state/ChatState.d.ts +6 -0
- package/dist/state/ChatState.d.ts.map +1 -1
- package/dist/state/ChatState.js +15 -0
- package/dist/state/ChatState.js.map +1 -1
- package/dist/utils/tools.d.ts +17 -8
- package/dist/utils/tools.d.ts.map +1 -1
- package/dist/utils/tools.js +20 -9
- package/dist/utils/tools.js.map +1 -1
- package/dist/views/Agents/AgentDescription.d.ts.map +1 -1
- package/dist/views/Agents/AgentDescription.js +5 -14
- package/dist/views/Agents/AgentDescription.js.map +1 -1
- package/dist/views/Agents/AgentsTab.d.ts.map +1 -1
- package/dist/views/Agents/AgentsTab.js +3 -2
- package/dist/views/Agents/AgentsTab.js.map +1 -1
- package/dist/views/Chat/ChatMessage.d.ts +1 -1
- package/dist/views/Chat/ChatMessage.d.ts.map +1 -1
- package/dist/views/Chat/ChatMessage.js +19 -20
- package/dist/views/Chat/ChatMessage.js.map +1 -1
- package/dist/views/Chat/StepsList.d.ts +2 -8
- package/dist/views/Chat/StepsList.d.ts.map +1 -1
- package/dist/views/Chat/StepsList.js +8 -7
- package/dist/views/Chat/StepsList.js.map +1 -1
- package/dist/views/ChatHistory/utils.d.ts.map +1 -1
- package/dist/views/ChatHistory/utils.js +94 -2
- package/dist/views/ChatHistory/utils.js.map +1 -1
- package/dist/views/KnowledgeSources.d.ts +1 -1
- package/dist/views/KnowledgeSources.d.ts.map +1 -1
- package/dist/views/KnowledgeSources.js +31 -45
- package/dist/views/KnowledgeSources.js.map +1 -1
- package/dist/views/MessageInput/QuickCommandSelector.d.ts.map +1 -1
- package/dist/views/MessageInput/QuickCommandSelector.js +29 -52
- package/dist/views/MessageInput/QuickCommandSelector.js.map +1 -1
- package/dist/views/MessageInput/index.d.ts.map +1 -1
- package/dist/views/MessageInput/index.js +9 -1
- package/dist/views/MessageInput/index.js.map +1 -1
- package/dist/views/MessageInput/styled.d.ts.map +1 -1
- package/dist/views/MessageInput/styled.js +4 -0
- package/dist/views/MessageInput/styled.js.map +1 -1
- package/dist/views/Resources.js +8 -5
- package/dist/views/Resources.js.map +1 -1
- package/dist/views/Tools.js +1 -1
- package/dist/views/Tools.js.map +1 -1
- package/package.json +3 -3
- package/src/app-metadata.json +4 -4
- package/src/chat-interceptors/quick-commands.ts +2 -2
- package/src/chat-interceptors/send-message.ts +8 -19
- package/src/components/form/DescribedCheckboxGroup.tsx +61 -35
- package/src/context/hooks.ts +24 -0
- package/src/state/ChatEntry.ts +9 -1
- package/src/state/ChatState.ts +16 -0
- package/src/utils/tools.ts +28 -17
- package/src/views/Agents/AgentDescription.tsx +40 -36
- package/src/views/Agents/AgentsTab.tsx +8 -7
- package/src/views/Chat/ChatMessage.tsx +23 -23
- package/src/views/Chat/StepsList.tsx +9 -9
- package/src/views/ChatHistory/utils.ts +96 -3
- package/src/views/KnowledgeSources.tsx +57 -77
- package/src/views/MessageInput/QuickCommandSelector.tsx +39 -93
- package/src/views/MessageInput/index.tsx +10 -0
- package/src/views/MessageInput/styled.ts +4 -0
- package/src/views/Resources.tsx +11 -10
- package/src/views/Tools.tsx +1 -1
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { Box } from '@citric/core'
|
|
2
1
|
import { Button, Tab } from '@stack-spot/citric-react'
|
|
3
2
|
import { Placeholder } from '@stack-spot/portal-components/Placeholder'
|
|
4
3
|
import { aiClient, dataIntegrationClient, workspaceAiClient } from '@stack-spot/portal-network'
|
|
5
4
|
import { VisibilityLevelEnum } from '@stack-spot/portal-network/api/ai'
|
|
5
|
+
import { KnowledgeSourceItemResponse } from '@stack-spot/portal-network/api/dataIntegration'
|
|
6
6
|
import { WorkspaceResponse } from '@stack-spot/portal-network/api/workspace-ai'
|
|
7
7
|
import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
|
|
8
8
|
import React, { useCallback, useEffect, useMemo, useRef } from 'react'
|
|
9
|
-
import InfiniteScroll from 'react-infinite-scroll-component'
|
|
10
9
|
import { NavigationComponent } from '../components/ComponentNavigator'
|
|
11
10
|
import { DescribedCheckboxGroup } from '../components/form/DescribedCheckboxGroup'
|
|
12
11
|
import { RightPanelContentList } from '../components/RightPanelContentList'
|
|
@@ -66,13 +65,19 @@ const KnowledgeSourcesPanel = () => {
|
|
|
66
65
|
}, [chat])
|
|
67
66
|
|
|
68
67
|
const allTabsMap: Partial<Record<Scope, Omit<Tab, 'key'>>> = {
|
|
69
|
-
favorite: {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
+
},
|
|
73
76
|
shared: { label: t.shared, content: <KnowledgeSourcesTab key="shared" visibility="shared" allKS={allKS} onSubmit={onSubmit} /> },
|
|
74
|
-
workspace: {
|
|
75
|
-
|
|
77
|
+
workspace: {
|
|
78
|
+
label: t.spots,
|
|
79
|
+
content: <KnowledgeSourcesTabWorkspace key="workspace" visibility="workspace" allKS={allKS} onSubmit={onSubmit} />,
|
|
80
|
+
},
|
|
76
81
|
account: { label: t.account, content: <KnowledgeSourcesTab key="account" visibility="account" allKS={allKS} onSubmit={onSubmit} /> },
|
|
77
82
|
}
|
|
78
83
|
|
|
@@ -97,47 +102,29 @@ const KnowledgeSourcesPanel = () => {
|
|
|
97
102
|
|
|
98
103
|
export const KnowledgeSourcesTab = ({ visibility, allKS, onSubmit, workspaceId, showSubmitButton = true }: TabProps) => {
|
|
99
104
|
const t = useTranslate(dictionary)
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
ksListPages,
|
|
116
|
-
_isLoadingKnowledgeSources,
|
|
117
|
-
_ksListError,
|
|
118
|
-
{ fetchNextPage: _fetchNextPage, hasNextPage: _hasNextPage },
|
|
119
|
-
] = dataIntegrationClient.knowledgeSourcesV2.useStatefulInfiniteQuery(
|
|
120
|
-
{
|
|
121
|
-
order: 'a-to-z',
|
|
122
|
-
visibilityList: visibility ? [visibility] : [],
|
|
123
|
-
types: ['snippet', 'api', 'event', 'custom'],
|
|
124
|
-
size: 20,
|
|
125
|
-
},
|
|
126
|
-
{ enabled: true },
|
|
127
|
-
)
|
|
128
|
-
knowledgeSources = ksListPages?.flat() ?? []
|
|
129
|
-
fetchNextPage = _fetchNextPage
|
|
130
|
-
hasNextPage = _hasNextPage
|
|
131
|
-
isLoadingKnowledgeSources = _isLoadingKnowledgeSources
|
|
132
|
-
ksListError = _ksListError
|
|
133
|
-
}
|
|
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
|
|
134
120
|
|
|
135
121
|
const initialValue = useMemo(() => {
|
|
136
122
|
const currentlySelected = allKS.current?.map(ks => ks.id)
|
|
137
|
-
return knowledgeSources
|
|
138
|
-
}, [knowledgeSources
|
|
123
|
+
return knowledgeSources?.filter((ks: KnowledgeSourceItemResponse) => currentlySelected?.includes(ks.slug))
|
|
124
|
+
}, [knowledgeSources])
|
|
125
|
+
|
|
126
|
+
const listFavorites = dataIntegrationClient.knowledgeSourcesV2.useQuery({ visibilityList: ['favorite'] })?.items
|
|
139
127
|
|
|
140
|
-
const listFavorites = dataIntegrationClient.knowledgeSources.useQuery({ visibility: 'favorite' })
|
|
141
128
|
const [addFavorite, pendingAddFav] = dataIntegrationClient.addFavoriteKnowledgeSource.useMutation()
|
|
142
129
|
const [removeFavorite, pendingRemoveFav] = dataIntegrationClient.removeFavoriteKnowledgeSource.useMutation()
|
|
143
130
|
|
|
@@ -145,7 +132,7 @@ export const KnowledgeSourcesTab = ({ visibility, allKS, onSubmit, workspaceId,
|
|
|
145
132
|
try {
|
|
146
133
|
await removeFavorite({ slug: idOrSlug })
|
|
147
134
|
await aiClient.knowledgeSources.invalidate()
|
|
148
|
-
await dataIntegrationClient.
|
|
135
|
+
await dataIntegrationClient.knowledgeSourcesV2.invalidate()
|
|
149
136
|
} catch (error) {
|
|
150
137
|
// eslint-disable-next-line no-console
|
|
151
138
|
console.error(error)
|
|
@@ -156,7 +143,7 @@ export const KnowledgeSourcesTab = ({ visibility, allKS, onSubmit, workspaceId,
|
|
|
156
143
|
const onRemoveFavorite = (idOrSlug: string) => new Promise<boolean>(async (resolve, reject) => {
|
|
157
144
|
try {
|
|
158
145
|
await removeFavoriteKs(idOrSlug)
|
|
159
|
-
if (!pendingRemoveFav){
|
|
146
|
+
if (!pendingRemoveFav) {
|
|
160
147
|
resolve(true)
|
|
161
148
|
}
|
|
162
149
|
|
|
@@ -164,17 +151,14 @@ export const KnowledgeSourcesTab = ({ visibility, allKS, onSubmit, workspaceId,
|
|
|
164
151
|
// eslint-disable-next-line no-console
|
|
165
152
|
console.error(error)
|
|
166
153
|
reject(error)
|
|
167
|
-
}
|
|
154
|
+
}
|
|
168
155
|
})
|
|
169
156
|
|
|
170
|
-
if (isLoadingKnowledgeSources && knowledgeSources.length === 0) {return null}
|
|
171
|
-
if (ksListError) {return null}
|
|
172
|
-
|
|
173
157
|
const addFavoriteKs = async (idOrSlug: string) => {
|
|
174
158
|
try {
|
|
175
159
|
await addFavorite({ slug: idOrSlug })
|
|
176
160
|
await aiClient.knowledgeSources.invalidate()
|
|
177
|
-
await dataIntegrationClient.
|
|
161
|
+
await dataIntegrationClient.knowledgeSourcesV2.invalidate()
|
|
178
162
|
} catch (error) {
|
|
179
163
|
// eslint-disable-next-line no-console
|
|
180
164
|
console.error(error)
|
|
@@ -185,7 +169,7 @@ export const KnowledgeSourcesTab = ({ visibility, allKS, onSubmit, workspaceId,
|
|
|
185
169
|
const onAddFavorite = (idOrSlug: string) => new Promise<boolean>(async (resolve, reject) => {
|
|
186
170
|
try {
|
|
187
171
|
await addFavoriteKs(idOrSlug)
|
|
188
|
-
if (!pendingAddFav){
|
|
172
|
+
if (!pendingAddFav) {
|
|
189
173
|
resolve(true)
|
|
190
174
|
}
|
|
191
175
|
|
|
@@ -193,31 +177,27 @@ export const KnowledgeSourcesTab = ({ visibility, allKS, onSubmit, workspaceId,
|
|
|
193
177
|
// eslint-disable-next-line no-console
|
|
194
178
|
console.error(error)
|
|
195
179
|
reject(error)
|
|
196
|
-
}
|
|
180
|
+
}
|
|
197
181
|
})
|
|
198
182
|
|
|
199
|
-
return (
|
|
200
|
-
|
|
201
|
-
<
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
</InfiniteScroll>
|
|
218
|
-
</Box>
|
|
219
|
-
{!!knowledgeSources.length && showSubmitButton && <Button onClick={onSubmit}>{t.apply}</Button>}
|
|
220
|
-
</>
|
|
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
|
+
</>
|
|
221
201
|
)
|
|
222
202
|
}
|
|
223
203
|
|
|
@@ -228,7 +208,7 @@ export function KnowledgeSourcesTabWorkspace({ allKS, onSubmit }: TabProps) {
|
|
|
228
208
|
component: 'ks',
|
|
229
209
|
props: { visibility: 'workspace', workspaceId: workspace.id, allKS, onSubmit },
|
|
230
210
|
})
|
|
231
|
-
|
|
211
|
+
|
|
232
212
|
return <WorkspaceTabNavigator components={workspaceTabComponents} getNavigateParam={buildNavigateParams} />
|
|
233
213
|
}
|
|
234
214
|
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import { Box } from '@citric/core'
|
|
2
1
|
import { Icon } from '@stack-spot/citric-icons'
|
|
3
2
|
import { aiClient, workspaceAiClient } from '@stack-spot/portal-network'
|
|
4
3
|
import { QuickCommandResponse } from '@stack-spot/portal-network/api/ai'
|
|
5
|
-
import { useCallback
|
|
6
|
-
import InfiniteScroll from 'react-infinite-scroll-component'
|
|
4
|
+
import { useCallback } from 'react'
|
|
7
5
|
import { Selector } from '../../components/Selector'
|
|
8
6
|
import { useCurrentChat, useCurrentChatState, useWidgetState } from '../../context/hooks'
|
|
9
7
|
import { quickCommandRegex } from '../../regex'
|
|
@@ -79,103 +77,51 @@ export const QuickCommandSelector = ({ inputRef, isTrial }:
|
|
|
79
77
|
inputRef.current.focus()
|
|
80
78
|
}, [chat, inputRef])
|
|
81
79
|
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
)
|
|
91
|
-
|
|
92
|
-
const quickCommands = useMemo(() => quickCommandsPages, [quickCommandsPages])
|
|
93
|
-
|
|
94
|
-
const quickCommandsFiltered = useMemo(() => quickCommands.filter(
|
|
95
|
-
(qc) => qc.visibility_level.toLowerCase() !== 'workspace'), [quickCommands],
|
|
96
|
-
)
|
|
97
|
-
|
|
98
|
-
const workspaceQuickCommands = workspaceAiClient.workspacesContentsByType.useQuery({
|
|
99
|
-
contentType: 'quick_command',
|
|
100
|
-
}) || []
|
|
101
|
-
|
|
102
|
-
const workspaceQuickCommandsWithWorkspaceName: QuickCommandResponseWithSpaceName[] =
|
|
103
|
-
useMemo(
|
|
104
|
-
() =>
|
|
105
|
-
workspaceQuickCommands.flatMap(({ qcs, space_name }) =>
|
|
106
|
-
qcs?.map((qc) => ({ ...qc, spaceName: space_name })),
|
|
107
|
-
) as QuickCommandResponseWithSpaceName[],
|
|
108
|
-
[workspaceQuickCommands],
|
|
80
|
+
const getQuickCommands = () => {
|
|
81
|
+
if (spotId) {
|
|
82
|
+
return workspaceAiClient.getQCFromWorkspaceAi.useQuery({ workspaceId: spotId })
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const quickCommands = aiClient.allQuickCommands.useQuery({ order: 'a-to-z' })
|
|
86
|
+
const quickCommandsFiltered = quickCommands.filter(
|
|
87
|
+
(qc) => qc.visibility_level.toLowerCase() !== 'workspace',
|
|
109
88
|
)
|
|
110
89
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
: [...quickCommandsFiltered, ...workspaceQuickCommandsWithWorkspaceName]
|
|
90
|
+
const workspaceQuickCommands = workspaceAiClient.workspacesContentsByType.useQuery({
|
|
91
|
+
contentType: 'quick_command',
|
|
92
|
+
})
|
|
115
93
|
|
|
116
|
-
|
|
117
|
-
|
|
94
|
+
const workspaceQuickCommandsWithWorkspaceName: QuickCommandResponseWithSpaceName[] =
|
|
95
|
+
workspaceQuickCommands.flatMap(({ qcs, space_name }) =>
|
|
96
|
+
qcs?.map((qc) => ({ ...qc, spaceName: space_name })),
|
|
97
|
+
) as QuickCommandResponseWithSpaceName[]
|
|
118
98
|
|
|
119
|
-
|
|
99
|
+
return [...quickCommandsFiltered, ...workspaceQuickCommandsWithWorkspaceName]
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const QuickCommandItem = ({ slug, description, spaceName }: QuickCommandResponseWithSpaceName) => <>
|
|
120
103
|
<p className="selector-description">{spaceName}</p>
|
|
121
104
|
<p className="selector-title">/{slug?.toUpperCase()}</p>
|
|
122
105
|
<p className="selector-description">{description}</p>
|
|
123
106
|
</>
|
|
124
|
-
)
|
|
125
|
-
|
|
126
|
-
if (spotId) {
|
|
127
|
-
return (
|
|
128
|
-
<Selector
|
|
129
|
-
inputRef={inputRef}
|
|
130
|
-
favorite={{
|
|
131
|
-
useFavorites, onAddFavorite, onRemoveFavorite, favoriteIsSlug: true,
|
|
132
|
-
}}
|
|
133
|
-
selectorConfig={{
|
|
134
|
-
resourceName: 'Quick Command',
|
|
135
|
-
shortcut: '/',
|
|
136
|
-
icon: <Icon icon="QuickCommand" />,
|
|
137
|
-
searchProp: 'slug',
|
|
138
|
-
urlBuilder: (qc) => `/quick-command/${qc?.slug}`,
|
|
139
|
-
regex: quickCommandRegex,
|
|
140
|
-
sections: isTrial ? ['favorite', 'personal'] : ['favorite', 'personal', 'workspace', 'account', 'shared'],
|
|
141
|
-
isEnabled: isQuickCommandEnabled,
|
|
142
|
-
onSelect: onSelectItem,
|
|
143
|
-
renderComponentItem: QuickCommandItem,
|
|
144
|
-
useData: () => allQuickCommands,
|
|
145
|
-
}}
|
|
146
|
-
/>
|
|
147
|
-
)
|
|
148
|
-
}
|
|
149
107
|
|
|
150
|
-
return
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
urlBuilder: (qc) => `/quick-command/${qc?.slug}`,
|
|
170
|
-
regex: quickCommandRegex,
|
|
171
|
-
sections: isTrial ? ['favorite', 'personal'] : ['favorite', 'personal', 'workspace', 'account', 'shared'],
|
|
172
|
-
isEnabled: isQuickCommandEnabled,
|
|
173
|
-
onSelect: onSelectItem,
|
|
174
|
-
renderComponentItem: QuickCommandItem,
|
|
175
|
-
useData: () => allQuickCommands,
|
|
176
|
-
}}
|
|
177
|
-
/>
|
|
178
|
-
</InfiniteScroll>
|
|
179
|
-
</Box>
|
|
180
|
-
)
|
|
108
|
+
return <Selector
|
|
109
|
+
inputRef={inputRef}
|
|
110
|
+
favorite={{
|
|
111
|
+
useFavorites, onAddFavorite, onRemoveFavorite, favoriteIsSlug: true,
|
|
112
|
+
}}
|
|
113
|
+
selectorConfig={{
|
|
114
|
+
resourceName: 'Quick Command',
|
|
115
|
+
shortcut: '/',
|
|
116
|
+
icon: <Icon icon="QuickCommand" />,
|
|
117
|
+
searchProp: 'slug',
|
|
118
|
+
urlBuilder: (qc) => `/quick-command/${qc?.slug}`,
|
|
119
|
+
regex: quickCommandRegex,
|
|
120
|
+
sections: isTrial ? ['favorite', 'personal'] : ['favorite', 'personal', 'workspace', 'account', 'shared'],
|
|
121
|
+
isEnabled: isQuickCommandEnabled,
|
|
122
|
+
onSelect: onSelectItem,
|
|
123
|
+
renderComponentItem: QuickCommandItem,
|
|
124
|
+
useData: getQuickCommands,
|
|
125
|
+
}}
|
|
126
|
+
/>
|
|
181
127
|
}
|
|
@@ -39,6 +39,7 @@ export const MessageInput = ({ chatWindowRef, customInputMessage }:
|
|
|
39
39
|
const { handleKeyDown, handleKeyUp } = useUserEntryHistoryShortcut()
|
|
40
40
|
const isTrial = checkIsTrial()
|
|
41
41
|
const { isDragging, handleDrop, handleDragLeave } = useUploadDragDrop()
|
|
42
|
+
const [disabled, setDisabled] = useState(false)
|
|
42
43
|
|
|
43
44
|
usePasteUpload({
|
|
44
45
|
textAreaRef,
|
|
@@ -88,6 +89,14 @@ export const MessageInput = ({ chatWindowRef, customInputMessage }:
|
|
|
88
89
|
}, [chat, t])
|
|
89
90
|
|
|
90
91
|
const onSend = useCallback(async () => {
|
|
92
|
+
if (disabled) return
|
|
93
|
+
|
|
94
|
+
if (chat.get('isLoading')) {
|
|
95
|
+
setDisabled(true)
|
|
96
|
+
await chat.whenLoadingEnds()
|
|
97
|
+
setDisabled(false)
|
|
98
|
+
}
|
|
99
|
+
|
|
91
100
|
const message = chat.get('nextMessage')
|
|
92
101
|
const code = chat.get('codeSelection')
|
|
93
102
|
const language = chat.get('codeLanguage')
|
|
@@ -162,6 +171,7 @@ export const MessageInput = ({ chatWindowRef, customInputMessage }:
|
|
|
162
171
|
onKeyUp={handleKeyUp}
|
|
163
172
|
onIncreaseSize={() => setExpanded(false)}
|
|
164
173
|
onResetSize={() => !expansionLocked.current && setExpanded(true)}
|
|
174
|
+
disabled={disabled}
|
|
165
175
|
/>
|
|
166
176
|
</div>
|
|
167
177
|
</div>
|
package/src/views/Resources.tsx
CHANGED
|
@@ -46,29 +46,30 @@ const ResourcesPanel = () => {
|
|
|
46
46
|
const chat = widget.chatTabs.getAll().find(c => c.id === chatId)
|
|
47
47
|
return chat?.getMessages().find(m => m.id === messageId)?.getValue()
|
|
48
48
|
}, [messageId])
|
|
49
|
-
const [toolKits] = agentToolsClient.tools.useStatefulQuery({}, { enabled: !!message?.agent?.id })
|
|
50
49
|
const [agent] = agentToolsClient.agent.useStatefulQuery({ agentId: message?.agent?.id || '' },
|
|
51
50
|
{ enabled: !!message?.agent?.id })
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
const toolkits = useMemo(() => [
|
|
52
|
+
...agent?.toolkits?.builtin_toolkits ?? [],
|
|
53
|
+
...agent?.toolkits?.custom_toolkits ?? [],
|
|
54
|
+
...agent?.toolkits?.mcp_toolkits ?? [],
|
|
55
|
+
], [agent])
|
|
56
|
+
const tools = useMemo(() => message?.tools?.map(id => toolById(id, toolkits)), [messageId, toolkits])
|
|
56
57
|
const [agentsTools] = agentToolsClient.agentsByIds.useStatefulQuery({ searchAgentsRequest:{ ids: message?.tools || [] } })
|
|
57
|
-
const hasAgentTool = useMemo(() => message?.tools?.some(id => agentsTools?.find((agent) => agent.id === id)), [messageId
|
|
58
|
+
const hasAgentTool = useMemo(() => message?.tools?.some(id => agentsTools?.find((agent) => agent.id === id)), [messageId])
|
|
58
59
|
|
|
59
60
|
const header = (image?: string, label?: string) => (
|
|
60
61
|
<Row>
|
|
61
|
-
<ImageBox
|
|
62
|
+
<ImageBox>
|
|
62
63
|
<ImageWithFallback src={image} fallback={<Icon icon="Agent" />} aria-label={label} title={label} />
|
|
63
64
|
</ImageBox>
|
|
64
65
|
<Text style={{ marginLeft: '8px' }}>{label}</Text>
|
|
65
66
|
</Row>
|
|
66
67
|
)
|
|
67
|
-
|
|
68
|
-
return !!
|
|
68
|
+
|
|
69
|
+
return !!tools?.length && (
|
|
69
70
|
<>
|
|
70
71
|
<>
|
|
71
|
-
{
|
|
72
|
+
{tools.map(
|
|
72
73
|
(tool) =>
|
|
73
74
|
tool && (
|
|
74
75
|
<StyledAccordion key={tool.id} header={header(tool?.image, tool?.name)} appearance="card" maxHeight={120}>
|