@stack-spot/ai-chat-widget 1.18.0 → 1.20.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 +19 -0
- package/dist/StackspotAIWidget.d.ts +3 -2
- package/dist/StackspotAIWidget.d.ts.map +1 -1
- package/dist/StackspotAIWidget.js +5 -4
- package/dist/StackspotAIWidget.js.map +1 -1
- package/dist/app-metadata.json +6 -6
- package/dist/chat-interceptors/send-message.d.ts.map +1 -1
- package/dist/chat-interceptors/send-message.js +7 -2
- package/dist/chat-interceptors/send-message.js.map +1 -1
- package/dist/components/ComponentNavigator.d.ts +38 -0
- package/dist/components/ComponentNavigator.d.ts.map +1 -0
- package/dist/components/ComponentNavigator.js +33 -0
- package/dist/components/ComponentNavigator.js.map +1 -0
- package/dist/components/ListResource.d.ts +29 -0
- package/dist/components/ListResource.d.ts.map +1 -0
- package/dist/components/ListResource.js +17 -0
- package/dist/components/ListResource.js.map +1 -0
- package/dist/components/RightPanelForm.d.ts.map +1 -1
- package/dist/components/RightPanelForm.js +29 -1
- package/dist/components/RightPanelForm.js.map +1 -1
- package/dist/components/Selector/index.js +5 -5
- package/dist/components/Selector/index.js.map +1 -1
- package/dist/components/Selector/styled.d.ts +3 -1
- package/dist/components/Selector/styled.d.ts.map +1 -1
- package/dist/components/Selector/styled.js +2 -1
- package/dist/components/Selector/styled.js.map +1 -1
- package/dist/components/WorkspaceTabNavigator.d.ts +17 -0
- package/dist/components/WorkspaceTabNavigator.d.ts.map +1 -0
- package/dist/components/WorkspaceTabNavigator.js +95 -0
- package/dist/components/WorkspaceTabNavigator.js.map +1 -0
- package/dist/components/form/DescribedCheckboxGroup.d.ts.map +1 -1
- package/dist/components/form/DescribedCheckboxGroup.js +23 -2
- package/dist/components/form/DescribedCheckboxGroup.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/state/ChatEntry.d.ts +17 -0
- package/dist/state/ChatEntry.d.ts.map +1 -1
- package/dist/state/ChatEntry.js.map +1 -1
- package/dist/views/Agents/AgentsPanel.d.ts.map +1 -1
- package/dist/views/Agents/AgentsPanel.js +19 -11
- package/dist/views/Agents/AgentsPanel.js.map +1 -1
- package/dist/views/Agents/AgentsTab.d.ts +9 -3
- package/dist/views/Agents/AgentsTab.d.ts.map +1 -1
- package/dist/views/Agents/AgentsTab.js +25 -7
- package/dist/views/Agents/AgentsTab.js.map +1 -1
- package/dist/views/Agents/dictionary.d.ts +1 -1
- package/dist/views/Agents/dictionary.d.ts.map +1 -1
- package/dist/views/Agents/dictionary.js +2 -0
- package/dist/views/Agents/dictionary.js.map +1 -1
- package/dist/views/Chat/ChatMessage.d.ts +16 -2
- package/dist/views/Chat/ChatMessage.d.ts.map +1 -1
- package/dist/views/Chat/ChatMessage.js +14 -12
- package/dist/views/Chat/ChatMessage.js.map +1 -1
- package/dist/views/Chat/ChatMessages.d.ts +3 -2
- package/dist/views/Chat/ChatMessages.d.ts.map +1 -1
- package/dist/views/Chat/ChatMessages.js +2 -2
- package/dist/views/Chat/ChatMessages.js.map +1 -1
- package/dist/views/Chat/StepsList.js +2 -2
- package/dist/views/Chat/StepsList.js.map +1 -1
- package/dist/views/Chat/index.d.ts +3 -2
- package/dist/views/Chat/index.d.ts.map +1 -1
- package/dist/views/Chat/index.js +2 -2
- package/dist/views/Chat/index.js.map +1 -1
- package/dist/views/ChatHistory/utils.d.ts.map +1 -1
- package/dist/views/ChatHistory/utils.js +12 -3
- package/dist/views/ChatHistory/utils.js.map +1 -1
- package/dist/views/KnowledgeSources.d.ts +12 -0
- package/dist/views/KnowledgeSources.d.ts.map +1 -1
- package/dist/views/KnowledgeSources.js +20 -6
- package/dist/views/KnowledgeSources.js.map +1 -1
- package/dist/views/MessageInput/AgentSelector.d.ts.map +1 -1
- package/dist/views/MessageInput/AgentSelector.js +11 -7
- package/dist/views/MessageInput/AgentSelector.js.map +1 -1
- package/dist/views/MessageInput/ButtonGroup.js +2 -2
- package/dist/views/MessageInput/ButtonGroup.js.map +1 -1
- package/dist/views/MessageInput/QuickCommandSelector.d.ts.map +1 -1
- package/dist/views/MessageInput/QuickCommandSelector.js +12 -4
- package/dist/views/MessageInput/QuickCommandSelector.js.map +1 -1
- package/dist/views/MessageInput/dictionary.d.ts +1 -1
- package/dist/views/MessageInput/dictionary.d.ts.map +1 -1
- package/dist/views/MessageInput/dictionary.js +4 -4
- package/dist/views/MessageInput/dictionary.js.map +1 -1
- package/dist/views/Stacks.d.ts +9 -0
- package/dist/views/Stacks.d.ts.map +1 -1
- package/dist/views/Stacks.js +37 -14
- package/dist/views/Stacks.js.map +1 -1
- package/dist/views/Workspaces/WorkspacesTab.d.ts +20 -0
- package/dist/views/Workspaces/WorkspacesTab.d.ts.map +1 -0
- package/dist/views/Workspaces/WorkspacesTab.js +64 -0
- package/dist/views/Workspaces/WorkspacesTab.js.map +1 -0
- package/dist/views/{Workspaces.d.ts → Workspaces/index.d.ts} +1 -1
- package/dist/views/Workspaces/index.d.ts.map +1 -0
- package/dist/views/Workspaces/index.js +67 -0
- package/dist/views/Workspaces/index.js.map +1 -0
- package/package.json +3 -3
- package/src/StackspotAIWidget.tsx +20 -6
- package/src/app-metadata.json +6 -6
- package/src/chat-interceptors/send-message.ts +7 -2
- package/src/components/ComponentNavigator.tsx +103 -0
- package/src/components/ListResource.tsx +60 -0
- package/src/components/RightPanelForm.tsx +29 -1
- package/src/components/Selector/index.tsx +5 -5
- package/src/components/Selector/styled.ts +3 -2
- package/src/components/WorkspaceTabNavigator.tsx +175 -0
- package/src/components/form/DescribedCheckboxGroup.tsx +38 -7
- package/src/index.ts +2 -0
- package/src/state/ChatEntry.ts +17 -0
- package/src/views/Agents/AgentsPanel.tsx +21 -11
- package/src/views/Agents/AgentsTab.tsx +42 -9
- package/src/views/Agents/dictionary.ts +3 -0
- package/src/views/Chat/ChatMessage.tsx +32 -18
- package/src/views/Chat/ChatMessages.tsx +11 -4
- package/src/views/Chat/StepsList.tsx +2 -2
- package/src/views/Chat/index.tsx +4 -3
- package/src/views/ChatHistory/utils.ts +14 -3
- package/src/views/KnowledgeSources.tsx +37 -14
- package/src/views/MessageInput/AgentSelector.tsx +20 -8
- package/src/views/MessageInput/ButtonGroup.tsx +3 -3
- package/src/views/MessageInput/QuickCommandSelector.tsx +19 -6
- package/src/views/MessageInput/dictionary.ts +4 -4
- package/src/views/Stacks.tsx +57 -17
- package/src/views/Workspaces/WorkspacesTab.tsx +120 -0
- package/src/views/Workspaces/index.tsx +76 -0
- package/dist/views/Workspaces.d.ts.map +0 -1
- package/dist/views/Workspaces.js +0 -103
- package/dist/views/Workspaces.js.map +0 -1
- package/src/views/Workspaces.tsx +0 -137
|
@@ -2,21 +2,32 @@ import { Button, IconBox, Text } from '@citric/core'
|
|
|
2
2
|
import { Agent, Search } from '@citric/icons'
|
|
3
3
|
import { Placeholder } from '@stack-spot/portal-components/Placeholder'
|
|
4
4
|
import { MiniLogo } from '@stack-spot/portal-components/svg'
|
|
5
|
-
import { agentClient } from '@stack-spot/portal-network'
|
|
5
|
+
import { agentClient, workspaceAiClient } from '@stack-spot/portal-network'
|
|
6
6
|
import { AgentResponse, VisibilityLevel } from '@stack-spot/portal-network/api/agent'
|
|
7
|
-
import {
|
|
7
|
+
import { WorkspaceResponse } from '@stack-spot/portal-network/api/workspace-ai'
|
|
8
|
+
import { useCallback, useMemo, useState } from 'react'
|
|
8
9
|
import { ButtonFavorite } from '../../components/ButtonFavorite'
|
|
10
|
+
import { NavigationComponent } from '../../components/ComponentNavigator'
|
|
9
11
|
import { DescribedRadioGroup } from '../../components/form/DescribedRadioGroup'
|
|
10
12
|
import { IconInput } from '../../components/IconInput'
|
|
13
|
+
import { WorkspaceTabNavigator } from '../../components/WorkspaceTabNavigator'
|
|
11
14
|
import { useCurrentChat } from '../../context/hooks'
|
|
12
15
|
import { useRightPanel } from '../../right-panel/hooks'
|
|
16
|
+
import { ChatProperties } from '../../state/ChatState'
|
|
13
17
|
import { isAgentDefault } from '../../utils/agent'
|
|
14
18
|
import { AgentDescription } from './AgentDescription'
|
|
15
19
|
import { useAgentsDictionary } from './dictionary'
|
|
16
20
|
import { AgentLabel } from './styled'
|
|
17
21
|
import { useAgentFavorites } from './useAgentFavorites'
|
|
18
22
|
|
|
19
|
-
export
|
|
23
|
+
export interface AgentTabProps {
|
|
24
|
+
visibility: VisibilityLevel | 'BUILT-IN',
|
|
25
|
+
workspaceId?: string,
|
|
26
|
+
agent: React.MutableRefObject<ChatProperties['agent']>,
|
|
27
|
+
showSubmitButton?: boolean,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const AgentsTab = ({ visibility, workspaceId, agent, showSubmitButton = true }: AgentTabProps) => {
|
|
20
31
|
const t = useAgentsDictionary()
|
|
21
32
|
const { close } = useRightPanel()
|
|
22
33
|
const chat = useCurrentChat()
|
|
@@ -26,10 +37,14 @@ export const AgentsTab = ({ visibility }: { visibility: VisibilityLevel | 'BUILT
|
|
|
26
37
|
|
|
27
38
|
const agentsBuiltIn = agentClient.publicAgents.useQuery({})
|
|
28
39
|
const agentDefault = agentsBuiltIn.find((agent) => isAgentDefault(agent.slug))
|
|
29
|
-
const agents =
|
|
30
|
-
|
|
40
|
+
const agents = workspaceId
|
|
41
|
+
? workspaceAiClient.getAgentFromWorkspaceAi.useQuery({ workspaceId })
|
|
42
|
+
: visibility === 'BUILT-IN' ? agentsBuiltIn : agentClient.agents.useQuery({ visibility })
|
|
43
|
+
|
|
31
44
|
const [value, setValue] = useState<AgentResponse | undefined>(
|
|
32
|
-
|
|
45
|
+
agent.current
|
|
46
|
+
? agents.find(a => a.id === agent.current?.id)
|
|
47
|
+
: chat.get('agent') ? agents.find(a => a.id === chat.get('agent')?.id) : agentDefault,
|
|
33
48
|
)
|
|
34
49
|
|
|
35
50
|
const filtered = useMemo(
|
|
@@ -53,6 +68,13 @@ export const AgentsTab = ({ visibility }: { visibility: VisibilityLevel | 'BUILT
|
|
|
53
68
|
close()
|
|
54
69
|
}
|
|
55
70
|
|
|
71
|
+
const onChange = useCallback((newValue: AgentResponse) => {
|
|
72
|
+
const isBuiltIn = visibility === 'BUILT-IN' || agentsBuiltIn.some((agent) => agent.id === newValue.id)
|
|
73
|
+
|
|
74
|
+
setValue(newValue)
|
|
75
|
+
agent.current = { ...newValue, builtIn: isBuiltIn, label: newValue.name }
|
|
76
|
+
}, [])
|
|
77
|
+
|
|
56
78
|
return (
|
|
57
79
|
<>
|
|
58
80
|
<div className="content">
|
|
@@ -65,7 +87,7 @@ export const AgentsTab = ({ visibility }: { visibility: VisibilityLevel | 'BUILT
|
|
|
65
87
|
)}
|
|
66
88
|
keygen={a => a.id}
|
|
67
89
|
value={value}
|
|
68
|
-
onChange={
|
|
90
|
+
onChange={onChange}
|
|
69
91
|
renderLabel={({ name, avatar, id }) => (
|
|
70
92
|
<AgentLabel>
|
|
71
93
|
{id ? (avatar ? <img src={avatar} /> : <IconBox size="xs"><Agent /></IconBox>) : <MiniLogo />}
|
|
@@ -74,7 +96,7 @@ export const AgentsTab = ({ visibility }: { visibility: VisibilityLevel | 'BUILT
|
|
|
74
96
|
)}
|
|
75
97
|
renderDescription={a => <AgentDescription
|
|
76
98
|
agentId={a.id}
|
|
77
|
-
visibility={visibility}
|
|
99
|
+
visibility={visibility}
|
|
78
100
|
description={a.description}
|
|
79
101
|
llm={a.llm_config?.model_slug}
|
|
80
102
|
numberOfKnowledgeSources={a.knowledge_sources_config?.knowledge_sources?.length ?? 0}
|
|
@@ -89,7 +111,18 @@ export const AgentsTab = ({ visibility }: { visibility: VisibilityLevel | 'BUILT
|
|
|
89
111
|
<Placeholder title={t.noSearchResults} description={t.noSearchResultsDescription} className="no-data-placeholder" />}
|
|
90
112
|
{!agents.length && <Placeholder title={t.noData} description={t.noDataDescription} />}
|
|
91
113
|
</div>
|
|
92
|
-
{!!filtered.length && <Button onClick={submit} disabled={!value}>{t.apply}</Button>}
|
|
114
|
+
{!!filtered.length && showSubmitButton && <Button onClick={submit} disabled={!value}>{t.apply}</Button>}
|
|
93
115
|
</>
|
|
94
116
|
)
|
|
95
117
|
}
|
|
118
|
+
|
|
119
|
+
export function AgentsTabWorkspace({ agent, visibility, showSubmitButton }: AgentTabProps) {
|
|
120
|
+
const workspaceTabComponents = useMemo(() => ({ agent: AgentsTab }), [agent])
|
|
121
|
+
|
|
122
|
+
const buildNavigateParams = (workspace: WorkspaceResponse): NavigationComponent<typeof workspaceTabComponents> => ({
|
|
123
|
+
component: 'agent',
|
|
124
|
+
props: { visibility, workspaceId: workspace.id, agent, showSubmitButton },
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
return <WorkspaceTabNavigator components={workspaceTabComponents} getNavigateParam={buildNavigateParams} />
|
|
128
|
+
}
|
|
@@ -17,6 +17,7 @@ const dictionary = {
|
|
|
17
17
|
description: 'Description',
|
|
18
18
|
favorites: 'Favorites',
|
|
19
19
|
tools: 'Tools',
|
|
20
|
+
spots: 'Spots',
|
|
20
21
|
},
|
|
21
22
|
pt: {
|
|
22
23
|
title: 'Agentes',
|
|
@@ -34,6 +35,8 @@ const dictionary = {
|
|
|
34
35
|
description: 'Descrição',
|
|
35
36
|
favorites: 'Favoritos',
|
|
36
37
|
tools: 'Ferramentas',
|
|
38
|
+
spots: 'Spots',
|
|
39
|
+
|
|
37
40
|
},
|
|
38
41
|
} satisfies Dictionary
|
|
39
42
|
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
/* eslint-disable semi */
|
|
2
1
|
import { Box, Button, Checkbox, Flex, IconBox, Input, Label, Radio, Text } from '@citric/core'
|
|
3
2
|
import { Cog, Copy, Dislike, DislikeFill, Like, LikeFill, TimesCircle } from '@citric/icons'
|
|
4
3
|
import { Avatar, Badge, IconButton } from '@citric/ui'
|
|
5
4
|
import { agentClient } from '@stack-spot/portal-network'
|
|
6
5
|
import { listToClass } from '@stack-spot/portal-theme'
|
|
7
6
|
import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
|
|
8
|
-
import {
|
|
9
|
-
import { Dispatch, useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
|
7
|
+
import { createElement, Dispatch, useCallback, useMemo, useRef, useState } from 'react'
|
|
10
8
|
import { PhoneInput } from 'react-international-phone'
|
|
11
9
|
import 'react-international-phone/style.css'
|
|
12
10
|
import { Markdown } from '../../components/Markdown'
|
|
@@ -20,7 +18,18 @@ import { useChatScrollToBottomEffect } from './chat-scroll'
|
|
|
20
18
|
import { onCopyAll, onCopyCode, onLikeOrDislike } from './events'
|
|
21
19
|
import { StepsList } from './StepsList'
|
|
22
20
|
|
|
23
|
-
interface
|
|
21
|
+
export interface CustomMessage {
|
|
22
|
+
/**
|
|
23
|
+
* React component to render before each message in the chat. It receives the message as a prop.
|
|
24
|
+
*/
|
|
25
|
+
beforeMessage?: React.FC<{ message: ChatEntry }>,
|
|
26
|
+
/**
|
|
27
|
+
* React component to render after each message in the chat. It receives the message as a prop.
|
|
28
|
+
*/
|
|
29
|
+
afterMessage?: React.FC<{ message: ChatEntry }>,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface Props extends CustomMessage {
|
|
24
33
|
/**
|
|
25
34
|
* The ChatEntry to render.
|
|
26
35
|
*/
|
|
@@ -47,17 +56,6 @@ interface RenderInputsEntryProps {
|
|
|
47
56
|
|
|
48
57
|
const RenderInputsEntry = ({ isLast, entry, value, setValue, labels, setLabels }: RenderInputsEntryProps) => {
|
|
49
58
|
const chat = useCurrentChat()
|
|
50
|
-
|
|
51
|
-
const handleChange = useCallback(
|
|
52
|
-
debounce((data) => {
|
|
53
|
-
setValue((prevValue) => [...prevValue, data.target.value]);
|
|
54
|
-
}, 500),
|
|
55
|
-
[],
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
useEffect(() => () => {
|
|
59
|
-
handleChange.cancel();
|
|
60
|
-
}, [handleChange])
|
|
61
59
|
|
|
62
60
|
const renderInputs = () => {
|
|
63
61
|
if (entry.type === 'input-text') {
|
|
@@ -127,8 +125,22 @@ const RenderInputsEntry = ({ isLast, entry, value, setValue, labels, setLabels }
|
|
|
127
125
|
<Text ml={3}>{option.label}</Text>
|
|
128
126
|
{option.hasInput && option.value && labels.findIndex((label) => label === option.value)!== -1 &&
|
|
129
127
|
<Box w={4} ml={2}>
|
|
130
|
-
<Input
|
|
131
|
-
|
|
128
|
+
<Input
|
|
129
|
+
name={entry.name}
|
|
130
|
+
{...entry.validations}
|
|
131
|
+
onChange={(data) => {
|
|
132
|
+
const customIndex = value.findIndex(v => !entry.options?.map(o => o.label).includes(v))
|
|
133
|
+
if (customIndex === -1) {
|
|
134
|
+
setValue([...value, data.target.value])
|
|
135
|
+
} else {
|
|
136
|
+
const newValue = [...value]
|
|
137
|
+
newValue[customIndex] = data.target.value
|
|
138
|
+
setValue(newValue)
|
|
139
|
+
}
|
|
140
|
+
}}
|
|
141
|
+
required={true}
|
|
142
|
+
sx={{ height: '30px' }}
|
|
143
|
+
/>
|
|
132
144
|
</Box>
|
|
133
145
|
}
|
|
134
146
|
</Flex>
|
|
@@ -157,7 +169,7 @@ const RenderInputsEntry = ({ isLast, entry, value, setValue, labels, setLabels }
|
|
|
157
169
|
/**
|
|
158
170
|
* Renders a message (ChatEntry) in the chat.
|
|
159
171
|
*/
|
|
160
|
-
export const ChatMessage = ({ message, username, isLast }: Props) => {
|
|
172
|
+
export const ChatMessage = ({ message, username, isLast, beforeMessage, afterMessage }: Props) => {
|
|
161
173
|
const t = useTranslate(dictionary)
|
|
162
174
|
const [liked, setLiked] = useState<boolean | undefined>()
|
|
163
175
|
const [value, setValue] = useState<string[]>(message.getValue()?.initialValue ?? [])
|
|
@@ -271,6 +283,7 @@ export const ChatMessage = ({ message, username, isLast }: Props) => {
|
|
|
271
283
|
<li key={entry.messageId} className={entry.agentType} ref={ref}>
|
|
272
284
|
<div className="chat-message" ref={chatRef} onKeyDown={handleKeyDown} tabIndex={0}>
|
|
273
285
|
<div className={`user-info ${entry.agentType}`}>{userInfo}</div>
|
|
286
|
+
{beforeMessage && createElement(beforeMessage, { message })}
|
|
274
287
|
{(entry.content || entry.steps) && <div className={listToClass(['message-content', entry.card && 'card', entry.type])}>
|
|
275
288
|
{!!entry.badges?.length && <div className="badges">
|
|
276
289
|
{entry.badges.map((b, index) => <Badge key={index} palette={b.color ?? 'cyan'} appearance="square">{b.label}</Badge>)}
|
|
@@ -286,6 +299,7 @@ export const ChatMessage = ({ message, username, isLast }: Props) => {
|
|
|
286
299
|
<Text appearance="microtext1">{entry.error}</Text>
|
|
287
300
|
</div>
|
|
288
301
|
)}
|
|
302
|
+
{afterMessage && createElement(afterMessage, { message })}
|
|
289
303
|
{!!entry.tools?.length && <StackedBadge
|
|
290
304
|
aria-label={t.openToolsPanel}
|
|
291
305
|
title={t.openToolsPanel}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { useMemo, useRef } from 'react'
|
|
2
2
|
import { useChatMessages } from '../../context/hooks'
|
|
3
|
-
import { ChatMessage } from './ChatMessage'
|
|
3
|
+
import { ChatMessage, CustomMessage } from './ChatMessage'
|
|
4
4
|
import { ChatList } from './styled'
|
|
5
5
|
|
|
6
|
-
interface Props {
|
|
6
|
+
interface Props extends CustomMessage {
|
|
7
7
|
username: string,
|
|
8
8
|
chatId: string,
|
|
9
9
|
}
|
|
@@ -11,10 +11,17 @@ interface Props {
|
|
|
11
11
|
/**
|
|
12
12
|
* Renders all messages of a chat.
|
|
13
13
|
*/
|
|
14
|
-
export const ChatMessages = ({ chatId, username }: Props) => {
|
|
14
|
+
export const ChatMessages = ({ chatId, username, beforeMessage, afterMessage }: Props) => {
|
|
15
15
|
const messages = useChatMessages(chatId)
|
|
16
16
|
const items = useMemo(
|
|
17
|
-
() => messages.map((m, index) => <ChatMessage
|
|
17
|
+
() => messages.map((m, index) => <ChatMessage
|
|
18
|
+
key={m.id}
|
|
19
|
+
message={m}
|
|
20
|
+
username={username}
|
|
21
|
+
isLast={index === messages.length - 1}
|
|
22
|
+
beforeMessage={beforeMessage}
|
|
23
|
+
afterMessage={afterMessage}
|
|
24
|
+
/>),
|
|
18
25
|
[messages],
|
|
19
26
|
)
|
|
20
27
|
const ref = useRef<HTMLUListElement>(null)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Button, IconBox, Text } from '@citric/core'
|
|
2
|
-
import { CheckCircleFill,
|
|
2
|
+
import { CheckCircleFill, PlayFill, Spaces, TimesCircleFill } from '@citric/icons'
|
|
3
3
|
import { LoadingCircular } from '@citric/ui'
|
|
4
4
|
import { AnimatedHeight } from '@stack-spot/portal-components/AnimatedHeight'
|
|
5
5
|
import { ChatStep, StepChatStep } from '@stack-spot/portal-network'
|
|
@@ -27,7 +27,7 @@ function getStatusIcon(status: ChatStep['status']) {
|
|
|
27
27
|
switch (status) {
|
|
28
28
|
case 'error': return <IconBox {...iconBoxProps}><TimesCircleFill /></IconBox>
|
|
29
29
|
case 'success': return <IconBox {...iconBoxProps}><CheckCircleFill /></IconBox>
|
|
30
|
-
case 'pending': return <IconBox {...iconBoxProps}><
|
|
30
|
+
case 'pending': return <IconBox {...iconBoxProps}><Spaces /></IconBox>
|
|
31
31
|
case 'running': return <LoadingCircular className="loading" colorScheme="inverse" size="xs" />
|
|
32
32
|
}
|
|
33
33
|
}
|
package/src/views/Chat/index.tsx
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { useChatTabs } from '../../context/hooks'
|
|
2
|
+
import { CustomMessage } from './ChatMessage'
|
|
2
3
|
import { ChatMessages } from './ChatMessages'
|
|
3
4
|
|
|
4
|
-
interface Props {
|
|
5
|
+
interface Props extends CustomMessage {
|
|
5
6
|
/**
|
|
6
7
|
* The name of the user currently logged in.
|
|
7
8
|
*/
|
|
@@ -11,7 +12,7 @@ interface Props {
|
|
|
11
12
|
/**
|
|
12
13
|
* Renders the chat panel, with all of its messages.
|
|
13
14
|
*/
|
|
14
|
-
export const Chat = ({ username }: Props) => {
|
|
15
|
+
export const Chat = ({ username, beforeMessage, afterMessage }: Props) => {
|
|
15
16
|
const { active } = useChatTabs()
|
|
16
|
-
return <ChatMessages key={active.id} chatId={active.id} username={username} />
|
|
17
|
+
return <ChatMessages key={active.id} chatId={active.id} username={username} beforeMessage={beforeMessage} afterMessage={afterMessage} />
|
|
17
18
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { agentClient, aiClient, workspaceClient } from '@stack-spot/portal-network'
|
|
1
|
+
import { agentClient, aiClient, workspaceAiClient, workspaceClient } from '@stack-spot/portal-network'
|
|
2
2
|
import { ChatProperties } from '../../state/ChatState'
|
|
3
3
|
import { LabeledWithImage } from '../../state/types'
|
|
4
4
|
|
|
@@ -44,9 +44,20 @@ export async function findWorkspace(id: string | null): Promise<ChatProperties['
|
|
|
44
44
|
*/
|
|
45
45
|
export async function getAllAgents(): Promise<LabeledWithImage[]> {
|
|
46
46
|
try {
|
|
47
|
-
const [
|
|
47
|
+
const [agentsAccount, agentsPersonal, agentsShared, publicAgents, workspaceAgents] = await Promise.all([
|
|
48
|
+
agentClient.agents.query({ visibility: 'ACCOUNT' }),
|
|
49
|
+
agentClient.agents.query({ visibility: 'PERSONAL' }),
|
|
50
|
+
agentClient.agents.query({ visibility: 'SHARED' }),
|
|
51
|
+
agentClient.publicAgents.query({}),
|
|
52
|
+
|
|
53
|
+
workspaceAiClient.workspacesContentsByType.query({ contentType: 'agent' }),
|
|
54
|
+
])
|
|
55
|
+
|
|
56
|
+
const workspaceAgentsAsArray = workspaceAgents.flatMap(({ agents }) => agents)
|
|
48
57
|
const builtInAgents = publicAgents.map((a) => ({ id: a.id, label: a.name, image: a.avatar, slug: a.slug, builtIn: true }))
|
|
49
|
-
return
|
|
58
|
+
return [...agentsAccount, ...agentsPersonal, ...agentsShared, ...workspaceAgentsAsArray]
|
|
59
|
+
.map(a => ({ id: a?.id, label: a?.name, image: a?.avatar, slug: a?.slug, builtIn: false }))
|
|
60
|
+
.concat(builtInAgents)
|
|
50
61
|
} catch (error) {
|
|
51
62
|
// eslint-disable-next-line no-console
|
|
52
63
|
console.error(error)
|
|
@@ -1,24 +1,29 @@
|
|
|
1
1
|
import { Button } from '@citric/core'
|
|
2
2
|
import { Search } from '@citric/icons'
|
|
3
3
|
import { Placeholder } from '@stack-spot/portal-components/Placeholder'
|
|
4
|
-
import { aiClient, dataIntegrationClient } from '@stack-spot/portal-network'
|
|
4
|
+
import { aiClient, dataIntegrationClient, workspaceAiClient } from '@stack-spot/portal-network'
|
|
5
5
|
import { KnowledgeSourceItemResponse, VisibilityLevelEnum } from '@stack-spot/portal-network/api/ai'
|
|
6
|
+
import { WorkspaceResponse } from '@stack-spot/portal-network/api/workspace-ai'
|
|
6
7
|
import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
|
|
7
8
|
import { difference, uniqBy } from 'lodash'
|
|
8
9
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
|
9
10
|
import { ButtonFavorite } from '../components/ButtonFavorite'
|
|
11
|
+
import { NavigationComponent } from '../components/ComponentNavigator'
|
|
10
12
|
import { DescribedCheckboxGroup } from '../components/form/DescribedCheckboxGroup'
|
|
11
13
|
import { IconInput } from '../components/IconInput'
|
|
12
14
|
import { RightPanelTabs } from '../components/RightPanelTabs'
|
|
15
|
+
import { WorkspaceTabNavigator } from '../components/WorkspaceTabNavigator'
|
|
13
16
|
import { useCurrentChat, useWidget, useWidgetState } from '../context/hooks'
|
|
14
17
|
import { useRightPanel } from '../right-panel/hooks'
|
|
15
18
|
import { ChatProperties } from '../state/ChatState'
|
|
16
19
|
import { checkIsTrial } from '../utils/check-is-trial'
|
|
17
20
|
|
|
18
|
-
interface TabProps {
|
|
21
|
+
export interface TabProps {
|
|
19
22
|
visibility: VisibilityLevelEnum,
|
|
20
|
-
onSubmit: () => void,
|
|
21
23
|
allKS: React.MutableRefObject<ChatProperties['knowledgeSources']>,
|
|
24
|
+
workspaceId?: string,
|
|
25
|
+
showSubmitButton?: boolean,
|
|
26
|
+
onSubmit?: () => void,
|
|
22
27
|
}
|
|
23
28
|
|
|
24
29
|
export const KnowledgeSources = () => {
|
|
@@ -55,7 +60,7 @@ const KnowledgeSourcesPanel = () => {
|
|
|
55
60
|
useEffect(() => {
|
|
56
61
|
allKS.current = chat.get('knowledgeSources') ?? []
|
|
57
62
|
}, [chat])
|
|
58
|
-
|
|
63
|
+
|
|
59
64
|
const tabs = isTrial ? [
|
|
60
65
|
{ title: t.favorites, content: <KnowledgeSourcesTab key="favorite" visibility="favorite" allKS={allKS} onSubmit={onSubmit} /> },
|
|
61
66
|
{ title: t.personal, content: <KnowledgeSourcesTab key="personal" visibility="personal" allKS={allKS} onSubmit={onSubmit} /> },
|
|
@@ -63,19 +68,23 @@ const KnowledgeSourcesPanel = () => {
|
|
|
63
68
|
{ title: t.favorites, content: <KnowledgeSourcesTab key="favorite" visibility="favorite" allKS={allKS} onSubmit={onSubmit} /> },
|
|
64
69
|
{ title: t.personal, content: <KnowledgeSourcesTab key="personal" visibility="personal" allKS={allKS} onSubmit={onSubmit} /> },
|
|
65
70
|
{ title: t.shared, content: <KnowledgeSourcesTab key="shared" visibility="shared" allKS={allKS} onSubmit={onSubmit} /> },
|
|
66
|
-
{ title: t.
|
|
71
|
+
{ title: t.spots, content: <KnowledgeSourcesTabWorkspace key="workspace" visibility="workspace" allKS={allKS} onSubmit={onSubmit} /> },
|
|
72
|
+
{ title: t.account, content: <KnowledgeSourcesTab key="account" visibility="account" allKS={allKS} onSubmit={onSubmit} /> },
|
|
67
73
|
]
|
|
68
|
-
|
|
74
|
+
|
|
69
75
|
return <RightPanelTabs key={chat.id} tabs={tabs} />
|
|
70
76
|
}
|
|
71
77
|
|
|
72
|
-
const KnowledgeSourcesTab = ({ visibility, allKS, onSubmit }: TabProps) => {
|
|
78
|
+
export const KnowledgeSourcesTab = ({ visibility, allKS, onSubmit, workspaceId, showSubmitButton = true }: TabProps) => {
|
|
73
79
|
const t = useTranslate(dictionary)
|
|
74
80
|
const [filter, setFilter] = useState('')
|
|
75
|
-
|
|
76
|
-
const knowledgeSources =
|
|
77
|
-
|
|
78
|
-
|
|
81
|
+
|
|
82
|
+
const knowledgeSources = workspaceId
|
|
83
|
+
? workspaceAiClient.getKSFromWorkspaceAi.useQuery({ workspaceId })
|
|
84
|
+
: aiClient.knowledgeSources.useQuery({
|
|
85
|
+
visibility, order: 'a-to-z', types: ['snippet', 'api', 'event', 'custom'],
|
|
86
|
+
})
|
|
87
|
+
|
|
79
88
|
const listFavorites = dataIntegrationClient.knowledgeSources.useQuery({ visibility: 'favorite' })
|
|
80
89
|
const [addFavorite, pendingAddFav] = dataIntegrationClient.addFavoriteKnowledgeSource.useMutation()
|
|
81
90
|
const [removeFavorite, pendingRemoveFav] = dataIntegrationClient.removeFavoriteKnowledgeSource.useMutation()
|
|
@@ -131,7 +140,7 @@ const KnowledgeSourcesTab = ({ visibility, allKS, onSubmit }: TabProps) => {
|
|
|
131
140
|
reject(error)
|
|
132
141
|
}
|
|
133
142
|
})
|
|
134
|
-
|
|
143
|
+
|
|
135
144
|
const [value, setValue] = useState<KnowledgeSourceItemResponse[]>((() => {
|
|
136
145
|
const currentlySelected = allKS.current?.map(ks => ks.id)
|
|
137
146
|
return knowledgeSources.filter(ks => currentlySelected?.includes(ks.slug))
|
|
@@ -139,7 +148,7 @@ const KnowledgeSourcesTab = ({ visibility, allKS, onSubmit }: TabProps) => {
|
|
|
139
148
|
const filtered = useMemo(
|
|
140
149
|
() => filter
|
|
141
150
|
// Recreate the list so that the favorites list is taken into account
|
|
142
|
-
? knowledgeSources.filter(ks => value.includes(ks) || ks.name.toLocaleLowerCase().includes(filter.toLocaleLowerCase()))
|
|
151
|
+
? knowledgeSources.filter(ks => value.includes(ks) || ks.name.toLocaleLowerCase().includes(filter.toLocaleLowerCase()))
|
|
143
152
|
: [...knowledgeSources]
|
|
144
153
|
, [knowledgeSources, filter, value, listFavorites],
|
|
145
154
|
)
|
|
@@ -181,11 +190,23 @@ const KnowledgeSourcesTab = ({ visibility, allKS, onSubmit }: TabProps) => {
|
|
|
181
190
|
)}
|
|
182
191
|
{!filtered.length && <Placeholder title={t.noData} description={t.noDataDescription} className="no-data-placeholder" />}
|
|
183
192
|
</div>
|
|
184
|
-
{!!filtered.length && <Button onClick={onSubmit}>{t.apply}</Button>}
|
|
193
|
+
{!!filtered.length && showSubmitButton && <Button onClick={onSubmit}>{t.apply}</Button>}
|
|
185
194
|
</>
|
|
186
195
|
)
|
|
187
196
|
}
|
|
188
197
|
|
|
198
|
+
export function KnowledgeSourcesTabWorkspace({ allKS, onSubmit }: TabProps) {
|
|
199
|
+
const workspaceTabComponents = useMemo(() => ({ ks: KnowledgeSourcesTab }), [allKS, onSubmit])
|
|
200
|
+
|
|
201
|
+
const buildNavigateParams = (workspace: WorkspaceResponse): NavigationComponent<typeof workspaceTabComponents> => ({
|
|
202
|
+
component: 'ks',
|
|
203
|
+
props: { visibility: 'workspace', workspaceId: workspace.id, allKS, onSubmit },
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
return <WorkspaceTabNavigator components={workspaceTabComponents} getNavigateParam={buildNavigateParams} />
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
|
|
189
210
|
const dictionary = {
|
|
190
211
|
en: {
|
|
191
212
|
title: 'Knowledge Sources',
|
|
@@ -199,6 +220,7 @@ const dictionary = {
|
|
|
199
220
|
noSearchResultsDescription: 'Please, try another search term.',
|
|
200
221
|
noData: 'There are no knowledge sources in this category yet.',
|
|
201
222
|
noDataDescription: 'Use the tabs above to try other categories or use the AI portal to create new knowledge sources.',
|
|
223
|
+
spots: 'Spots',
|
|
202
224
|
},
|
|
203
225
|
pt: {
|
|
204
226
|
title: 'Knowledge Sources',
|
|
@@ -212,5 +234,6 @@ const dictionary = {
|
|
|
212
234
|
noSearchResultsDescription: 'Por favor, tente outra busca.',
|
|
213
235
|
noData: 'Ainda não há knowledge sources nesta categoria.',
|
|
214
236
|
noDataDescription: 'Use as abas acima para tentar outras categorias ou use o Portal AI para criar novos knowledge sources.',
|
|
237
|
+
spots: 'Spots',
|
|
215
238
|
},
|
|
216
239
|
} satisfies Dictionary
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Flex, IconBox, Image } from '@citric/core'
|
|
2
2
|
import { Agent } from '@citric/icons'
|
|
3
|
-
import { agentClient } from '@stack-spot/portal-network'
|
|
3
|
+
import { agentClient, workspaceAiClient } from '@stack-spot/portal-network'
|
|
4
4
|
import { AgentResponse } from '@stack-spot/portal-network/api/agent'
|
|
5
5
|
import { uniqBy } from 'lodash'
|
|
6
6
|
import { useCallback } from 'react'
|
|
@@ -9,17 +9,23 @@ import { useCurrentChat, useCurrentChatState } from '../../context/hooks'
|
|
|
9
9
|
import { agentRegex } from '../../regex'
|
|
10
10
|
import { useAgentFavorites } from '../Agents/useAgentFavorites'
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
type AgentWithSpaceName = AgentResponse & { spaceName?: string }
|
|
13
|
+
|
|
14
|
+
const AgentItem = ({ avatar, name, spaceName }: AgentWithSpaceName) => {
|
|
13
15
|
const avatarComponent = avatar ? <Image width="32" height="32" radius="full" src={avatar} /> : <IconBox size="md"><Agent /></IconBox>
|
|
14
16
|
|
|
15
17
|
return <Flex flexWrap="nowrap" alignItems="center" sx={{ gap: '8px' }}>
|
|
16
18
|
{avatarComponent}
|
|
17
|
-
<
|
|
19
|
+
<div>
|
|
20
|
+
<p className="selector-description">{spaceName}</p>
|
|
21
|
+
<p className="selector-title">{name}</p>
|
|
22
|
+
</div>
|
|
18
23
|
</Flex>
|
|
19
24
|
}
|
|
20
25
|
|
|
21
26
|
export const AgentSelector = ({ inputRef, isTrial }: { isTrial: boolean,
|
|
22
|
-
inputRef: React.RefObject<HTMLTextAreaElement | HTMLInputElement>,
|
|
27
|
+
inputRef: React.RefObject<HTMLTextAreaElement | HTMLInputElement>,
|
|
28
|
+
}) => {
|
|
23
29
|
const chat = useCurrentChat()
|
|
24
30
|
const isAgentEnabled = useCurrentChatState('features').agent
|
|
25
31
|
|
|
@@ -33,8 +39,10 @@ export const AgentSelector = ({ inputRef, isTrial }: { isTrial: boolean,
|
|
|
33
39
|
const isBuiltIn = agent.visibility_level === 'builtIn' || builtInsAgents.some((builtInAgent) => builtInAgent.id === agent.id)
|
|
34
40
|
chat.set(
|
|
35
41
|
'agent',
|
|
36
|
-
{
|
|
37
|
-
|
|
42
|
+
{
|
|
43
|
+
id: agent.id, label: agent.name, image: agent.avatar, slug: agent.slug,
|
|
44
|
+
builtIn: isBuiltIn, visibility_level: agent.visibility_level,
|
|
45
|
+
},
|
|
38
46
|
)
|
|
39
47
|
|
|
40
48
|
if (!inputRef.current) return
|
|
@@ -46,6 +54,10 @@ export const AgentSelector = ({ inputRef, isTrial }: { isTrial: boolean,
|
|
|
46
54
|
const personalAgents = agentClient.agents.useQuery({ visibility: 'PERSONAL' })
|
|
47
55
|
const publicAgents = agentClient.publicAgents.useQuery({})
|
|
48
56
|
const builtInsAgents = [...publicAgents.map((agent) => ({ ...agent, visibility_level: 'builtIn' }))]
|
|
57
|
+
const workspaceAgents = workspaceAiClient.workspacesContentsByType.useQuery({ contentType: 'agent' })
|
|
58
|
+
|
|
59
|
+
const workspaceAgentsWithWorkspaceName = workspaceAgents.flatMap(({ agents, space_name }) =>
|
|
60
|
+
agents?.map((agent) => ({ ...agent, spaceName: space_name }))) as AgentWithSpaceName[]
|
|
49
61
|
let accountAgents: AgentResponse[] = []
|
|
50
62
|
let sharedAgents: AgentResponse[] = []
|
|
51
63
|
if (!isTrial) {
|
|
@@ -53,7 +65,7 @@ export const AgentSelector = ({ inputRef, isTrial }: { isTrial: boolean,
|
|
|
53
65
|
sharedAgents = agentClient.agents.useQuery({ visibility: 'SHARED' }) || []
|
|
54
66
|
}
|
|
55
67
|
|
|
56
|
-
return uniqBy([...personalAgents, ...accountAgents, ...sharedAgents, ...builtInsAgents], 'id')
|
|
68
|
+
return uniqBy([...personalAgents, ...workspaceAgentsWithWorkspaceName, ...accountAgents, ...sharedAgents, ...builtInsAgents], 'id')
|
|
57
69
|
}
|
|
58
70
|
|
|
59
71
|
return <Selector
|
|
@@ -66,7 +78,7 @@ export const AgentSelector = ({ inputRef, isTrial }: { isTrial: boolean,
|
|
|
66
78
|
regex: agentRegex,
|
|
67
79
|
urlBuilder: (agent) => `/agents/${agent?.id}`,
|
|
68
80
|
searchProp: 'name',
|
|
69
|
-
sections: isTrial ? ['favorite', 'personal', 'builtIn'] : ['favorite', 'personal', 'account', 'shared', 'builtIn'],
|
|
81
|
+
sections: isTrial ? ['favorite', 'personal', 'builtIn'] : ['favorite', 'personal', 'workspace', 'account', 'shared', 'builtIn'],
|
|
70
82
|
renderComponentItem: AgentItem,
|
|
71
83
|
isEnabled: isAgentEnabled,
|
|
72
84
|
onSelect: onSelectItem,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChevronRight, Code, KnowledgeSource, Send, Stack, Times
|
|
1
|
+
import { ChevronRight, Code, KnowledgeSource, Send, Spaces, Stack, Times } from '@citric/icons'
|
|
2
2
|
import { IconButton } from '@citric/ui'
|
|
3
3
|
import { listToClass } from '@stack-spot/portal-theme'
|
|
4
4
|
import { useEffect, useRef } from 'react'
|
|
@@ -62,8 +62,8 @@ export const ButtonGroup = ({ onSend, onCancel, expanded, setExpanded, isLoading
|
|
|
62
62
|
style={{ width: expanded ? featureButtonsWidth.current : 0 }}
|
|
63
63
|
>
|
|
64
64
|
{features.workspace && (
|
|
65
|
-
<IconButton aria-label={t.
|
|
66
|
-
<
|
|
65
|
+
<IconButton aria-label={t.spot} title={t.spot} onClick={() => widget.set('panel', 'workspace')}>
|
|
66
|
+
<Spaces />
|
|
67
67
|
</IconButton>
|
|
68
68
|
)}
|
|
69
69
|
{features.knowledgeSource && (
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { QuickCommand } from '@citric/icons'
|
|
2
|
-
import { aiClient } from '@stack-spot/portal-network'
|
|
3
|
-
import {
|
|
2
|
+
import { aiClient, workspaceAiClient } from '@stack-spot/portal-network'
|
|
3
|
+
import { QuickCommandResponse } 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 } from '../../context/hooks'
|
|
7
7
|
import { quickCommandRegex } from '../../regex'
|
|
8
8
|
|
|
9
|
+
type QuickCommandResponseWithSpaceName = QuickCommandResponse & { spaceName?: string }
|
|
10
|
+
|
|
9
11
|
export const QuickCommandSelector = ({ inputRef, isTrial }:
|
|
10
12
|
{ isTrial: boolean, inputRef: React.RefObject<HTMLTextAreaElement | HTMLInputElement> }) => {
|
|
11
13
|
const chat = useCurrentChat()
|
|
@@ -65,7 +67,7 @@ export const QuickCommandSelector = ({ inputRef, isTrial }:
|
|
|
65
67
|
}
|
|
66
68
|
})
|
|
67
69
|
|
|
68
|
-
const onSelectItem = useCallback((qc:
|
|
70
|
+
const onSelectItem = useCallback((qc: QuickCommandResponseWithSpaceName) => {
|
|
69
71
|
const newValue = `/${qc.slug}`
|
|
70
72
|
chat.set('nextMessage', newValue)
|
|
71
73
|
|
|
@@ -74,8 +76,19 @@ export const QuickCommandSelector = ({ inputRef, isTrial }:
|
|
|
74
76
|
inputRef.current.focus()
|
|
75
77
|
}, [chat, inputRef])
|
|
76
78
|
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
+
const getQuickCommands = () => {
|
|
80
|
+
const quickCommands = aiClient.quickCommands.useQuery({ order: 'a-to-z' })
|
|
81
|
+
const quickCommandsFiltered = quickCommands.filter((qc) => qc.visibility_level.toLowerCase() !== 'workspace')
|
|
82
|
+
const workspaceQuickCommands = workspaceAiClient.workspacesContentsByType.useQuery({ contentType: 'quick_command' })
|
|
83
|
+
const workspaceQuickCommandsWithWorkspaceName: QuickCommandResponseWithSpaceName[] = workspaceQuickCommands
|
|
84
|
+
.flatMap(({ qcs, space_name }) => qcs?.map((qc) => ({ ...qc, spaceName: space_name }))) as QuickCommandResponseWithSpaceName[]
|
|
85
|
+
|
|
86
|
+
return [...quickCommandsFiltered, ...workspaceQuickCommandsWithWorkspaceName]
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const QuickCommandItem = ({ slug, description, spaceName }: QuickCommandResponseWithSpaceName) => <>
|
|
90
|
+
<p className="selector-description">{spaceName}</p>
|
|
91
|
+
<p className="selector-title">/{slug?.toUpperCase()}</p>
|
|
79
92
|
<p className="selector-description">{description}</p>
|
|
80
93
|
</>
|
|
81
94
|
|
|
@@ -95,7 +108,7 @@ export const QuickCommandSelector = ({ inputRef, isTrial }:
|
|
|
95
108
|
isEnabled: isQuickCommandEnabled,
|
|
96
109
|
onSelect: onSelectItem,
|
|
97
110
|
renderComponentItem: QuickCommandItem,
|
|
98
|
-
useData:
|
|
111
|
+
useData: getQuickCommands,
|
|
99
112
|
}}
|
|
100
113
|
/>
|
|
101
114
|
}
|
|
@@ -4,7 +4,7 @@ const dictionary = {
|
|
|
4
4
|
en: {
|
|
5
5
|
stack: 'Select stack',
|
|
6
6
|
code: 'Open code editor',
|
|
7
|
-
|
|
7
|
+
spot: 'Select spot',
|
|
8
8
|
knowledgeSource: 'Select knowledge sources',
|
|
9
9
|
agent: 'Select agent',
|
|
10
10
|
collapse: 'Hide buttons',
|
|
@@ -14,7 +14,7 @@ const dictionary = {
|
|
|
14
14
|
cancel: 'Cancel',
|
|
15
15
|
removeConfig: 'Remove all the configuration',
|
|
16
16
|
removeStack: 'Stop using the current stack',
|
|
17
|
-
removeWorkspace: 'Stop using the current
|
|
17
|
+
removeWorkspace: 'Stop using the current spot',
|
|
18
18
|
removeKS: 'Stop using this knowledge source',
|
|
19
19
|
selected: 'Selected',
|
|
20
20
|
removeSelection: 'Remove current code selection',
|
|
@@ -23,7 +23,7 @@ const dictionary = {
|
|
|
23
23
|
pt: {
|
|
24
24
|
stack: 'Selecionar stack',
|
|
25
25
|
code: 'Abrir editor de código',
|
|
26
|
-
|
|
26
|
+
spot: 'Selecionar spot',
|
|
27
27
|
knowledgeSource: 'Selecionar knowledge sources',
|
|
28
28
|
agent: 'Selecionar agente',
|
|
29
29
|
collapse: 'Esconder botões',
|
|
@@ -33,7 +33,7 @@ const dictionary = {
|
|
|
33
33
|
cancel: 'Cancelar',
|
|
34
34
|
removeConfig: 'Remover todas as configurações',
|
|
35
35
|
removeStack: 'Parar de usar a stack atual',
|
|
36
|
-
removeWorkspace: 'Parar de usar o
|
|
36
|
+
removeWorkspace: 'Parar de usar o spot atual',
|
|
37
37
|
removeKS: 'Parar de usar este knowledge source',
|
|
38
38
|
selected: 'Selecionado',
|
|
39
39
|
removeSelection: 'Desfazer seleção de código',
|