@stack-spot/ai-chat-widget 1.13.2-beta.0 → 1.14.0-beta.1
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 +21 -0
- package/dist/StackspotAIWidget.d.ts.map +1 -1
- package/dist/StackspotAIWidget.js +3 -2
- package/dist/StackspotAIWidget.js.map +1 -1
- package/dist/app-metadata.json +3 -3
- package/dist/chat-interceptors/CustomInputs.d.ts +2 -2
- package/dist/chat-interceptors/CustomInputs.d.ts.map +1 -1
- package/dist/chat-interceptors/CustomInputs.js.map +1 -1
- 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 +2 -0
- package/dist/chat-interceptors/send-message.js.map +1 -1
- package/dist/components/Markdown.d.ts.map +1 -1
- package/dist/components/Markdown.js +1 -1
- package/dist/components/Markdown.js.map +1 -1
- package/dist/components/StackedBadge.d.ts +14 -0
- package/dist/components/StackedBadge.d.ts.map +1 -0
- package/dist/components/StackedBadge.js +56 -0
- package/dist/components/StackedBadge.js.map +1 -0
- package/dist/components/ToolBadge.d.ts +14 -0
- package/dist/components/ToolBadge.d.ts.map +1 -0
- package/dist/components/ToolBadge.js +108 -0
- package/dist/components/ToolBadge.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/state/ChatEntry.d.ts +12 -19
- package/dist/state/ChatEntry.d.ts.map +1 -1
- package/dist/state/ChatEntry.js.map +1 -1
- package/dist/state/ChatState.d.ts +2 -5
- package/dist/state/ChatState.d.ts.map +1 -1
- package/dist/state/WidgetState.d.ts +3 -4
- package/dist/state/WidgetState.d.ts.map +1 -1
- package/dist/state/WidgetState.js +1 -12
- package/dist/state/WidgetState.js.map +1 -1
- package/dist/state/types.d.ts +3 -1
- package/dist/state/types.d.ts.map +1 -1
- package/dist/utils/tools.d.ts +7 -0
- package/dist/utils/tools.d.ts.map +1 -0
- package/dist/utils/tools.js +9 -0
- package/dist/utils/tools.js.map +1 -0
- package/dist/views/Agents/AgentDescription.d.ts.map +1 -1
- package/dist/views/Agents/AgentDescription.js +11 -1
- 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 +4 -8
- 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/Agents/styled.js +1 -1
- package/dist/views/Chat/AgentInfo.d.ts +2 -2
- package/dist/views/Chat/AgentInfo.d.ts.map +1 -1
- package/dist/views/Chat/AgentInfo.js +3 -3
- package/dist/views/Chat/AgentInfo.js.map +1 -1
- package/dist/views/Chat/ChatMessage.d.ts.map +1 -1
- package/dist/views/Chat/ChatMessage.js +22 -4
- package/dist/views/Chat/ChatMessage.js.map +1 -1
- package/dist/views/Chat/StepsList.d.ts +2 -2
- package/dist/views/Chat/StepsList.d.ts.map +1 -1
- package/dist/views/Chat/StepsList.js +2 -2
- package/dist/views/Chat/StepsList.js.map +1 -1
- package/dist/views/Chat/styled.d.ts.map +1 -1
- package/dist/views/Chat/styled.js +21 -12
- package/dist/views/Chat/styled.js.map +1 -1
- package/dist/views/ChatHistory/utils.d.ts +2 -2
- package/dist/views/ChatHistory/utils.d.ts.map +1 -1
- package/dist/views/ChatTabSelection.d.ts.map +1 -1
- package/dist/views/ChatTabSelection.js +16 -2
- package/dist/views/ChatTabSelection.js.map +1 -1
- package/dist/views/MessageInput/AgentSelector.d.ts.map +1 -1
- package/dist/views/MessageInput/AgentSelector.js +5 -9
- package/dist/views/MessageInput/AgentSelector.js.map +1 -1
- package/dist/views/MessageInput/ButtonAgent.d.ts.map +1 -1
- package/dist/views/MessageInput/ButtonAgent.js +21 -2
- package/dist/views/MessageInput/ButtonAgent.js.map +1 -1
- package/dist/views/MessageInput/index.js +2 -2
- package/dist/views/MessageInput/index.js.map +1 -1
- package/dist/views/{Tools → Steps}/FlowChart/HandleGroup.d.ts.map +1 -1
- package/dist/views/{Tools → Steps}/FlowChart/HandleGroup.js.map +1 -1
- package/dist/views/{Tools → Steps}/FlowChart/NodeStep.d.ts.map +1 -1
- package/dist/views/Steps/FlowChart/NodeStep.js +13 -0
- package/dist/views/Steps/FlowChart/NodeStep.js.map +1 -0
- package/dist/views/Steps/FlowChart/index.d.ts +10 -0
- package/dist/views/Steps/FlowChart/index.d.ts.map +1 -0
- package/dist/views/{Tools → Steps}/FlowChart/index.js +1 -5
- package/dist/views/{Tools → Steps}/FlowChart/index.js.map +1 -1
- package/dist/views/{Tools → Steps}/FlowChart/layout.d.ts.map +1 -1
- package/dist/views/{Tools → Steps}/FlowChart/layout.js.map +1 -1
- package/dist/views/{Tools → Steps}/FlowChart/styled.d.ts.map +1 -1
- package/dist/views/{Tools → Steps}/FlowChart/styled.js +0 -49
- package/dist/views/{Tools → Steps}/FlowChart/styled.js.map +1 -1
- package/dist/views/{Tools → Steps}/FlowChart/types.d.ts +3 -3
- package/dist/views/Steps/FlowChart/types.d.ts.map +1 -0
- package/dist/views/Steps/FlowChart/types.js.map +1 -0
- package/dist/views/Steps/StepModal.d.ts +9 -0
- package/dist/views/Steps/StepModal.d.ts.map +1 -0
- package/dist/views/Steps/StepModal.js +124 -0
- package/dist/views/Steps/StepModal.js.map +1 -0
- package/dist/views/Steps/StepsPanel.d.ts +6 -0
- package/dist/views/Steps/StepsPanel.d.ts.map +1 -0
- package/dist/views/{Tools/ToolsPanel.js → Steps/StepsPanel.js} +3 -3
- package/dist/views/{Tools/ToolsPanel.js.map → Steps/StepsPanel.js.map} +1 -1
- package/dist/views/{Tools → Steps}/dictionary.d.ts +9 -11
- package/dist/views/Steps/dictionary.d.ts.map +1 -0
- package/dist/views/{Tools → Steps}/dictionary.js +9 -11
- package/dist/views/Steps/dictionary.js.map +1 -0
- package/dist/views/{Tools → Steps}/index.d.ts +1 -1
- package/dist/views/Steps/index.d.ts.map +1 -0
- package/dist/views/{Tools → Steps}/index.js +10 -10
- package/dist/views/{Tools → Steps}/index.js.map +1 -1
- package/dist/views/Steps/utils.d.ts +6 -0
- package/dist/views/Steps/utils.d.ts.map +1 -0
- package/dist/views/{Tools → Steps}/utils.js.map +1 -1
- package/dist/views/Tools.d.ts +2 -0
- package/dist/views/Tools.d.ts.map +1 -0
- package/dist/views/Tools.js +51 -0
- package/dist/views/Tools.js.map +1 -0
- package/package.json +2 -2
- package/src/StackspotAIWidget.tsx +2 -0
- package/src/app-metadata.json +3 -3
- package/src/chat-interceptors/CustomInputs.ts +3 -3
- package/src/chat-interceptors/quick-commands.ts +2 -2
- package/src/chat-interceptors/send-message.ts +4 -2
- package/src/components/Markdown.tsx +1 -0
- package/src/components/StackedBadge.tsx +77 -0
- package/src/components/ToolBadge.tsx +146 -0
- package/src/index.ts +1 -1
- package/src/state/ChatEntry.ts +12 -20
- package/src/state/ChatState.ts +2 -2
- package/src/state/WidgetState.ts +4 -16
- package/src/state/types.ts +4 -1
- package/src/utils/agent.ts +1 -1
- package/src/utils/tools.ts +11 -0
- package/src/views/Agents/AgentDescription.tsx +14 -0
- package/src/views/Agents/AgentsTab.tsx +5 -10
- package/src/views/Agents/dictionary.ts +2 -0
- package/src/views/Agents/styled.ts +1 -1
- package/src/views/Chat/AgentInfo.tsx +6 -6
- package/src/views/Chat/ChatMessage.tsx +34 -4
- package/src/views/Chat/StepsList.tsx +6 -6
- package/src/views/Chat/styled.ts +21 -12
- package/src/views/ChatHistory/utils.ts +2 -2
- package/src/views/ChatTabSelection.tsx +22 -4
- package/src/views/MessageInput/AgentSelector.tsx +7 -9
- package/src/views/MessageInput/ButtonAgent.tsx +26 -2
- package/src/views/MessageInput/index.tsx +2 -2
- package/src/views/{Tools → Steps}/FlowChart/NodeStep.tsx +11 -23
- package/src/views/{Tools → Steps}/FlowChart/index.tsx +3 -7
- package/src/views/{Tools → Steps}/FlowChart/styled.ts +0 -49
- package/src/views/{Tools → Steps}/FlowChart/types.ts +3 -3
- package/src/views/Steps/StepModal.tsx +216 -0
- package/src/views/{Tools/ToolsPanel.tsx → Steps/StepsPanel.tsx} +2 -2
- package/src/views/{Tools → Steps}/dictionary.ts +9 -11
- package/src/views/{Tools → Steps}/index.tsx +10 -10
- package/src/views/{Tools → Steps}/utils.tsx +4 -4
- package/src/views/Tools.tsx +71 -0
- package/dist/views/Tools/FlowChart/NodeStep.js +0 -15
- package/dist/views/Tools/FlowChart/NodeStep.js.map +0 -1
- package/dist/views/Tools/FlowChart/index.d.ts +0 -9
- package/dist/views/Tools/FlowChart/index.d.ts.map +0 -1
- package/dist/views/Tools/FlowChart/types.d.ts.map +0 -1
- package/dist/views/Tools/FlowChart/types.js.map +0 -1
- package/dist/views/Tools/StepModal.d.ts +0 -9
- package/dist/views/Tools/StepModal.d.ts.map +0 -1
- package/dist/views/Tools/StepModal.js +0 -156
- package/dist/views/Tools/StepModal.js.map +0 -1
- package/dist/views/Tools/ToolsPanel.d.ts +0 -6
- package/dist/views/Tools/ToolsPanel.d.ts.map +0 -1
- package/dist/views/Tools/dictionary.d.ts.map +0 -1
- package/dist/views/Tools/dictionary.js.map +0 -1
- package/dist/views/Tools/index.d.ts.map +0 -1
- package/dist/views/Tools/utils.d.ts +0 -6
- package/dist/views/Tools/utils.d.ts.map +0 -1
- package/src/views/Tools/StepModal.tsx +0 -247
- /package/dist/views/{Tools → Steps}/FlowChart/HandleGroup.d.ts +0 -0
- /package/dist/views/{Tools → Steps}/FlowChart/HandleGroup.js +0 -0
- /package/dist/views/{Tools → Steps}/FlowChart/NodeStep.d.ts +0 -0
- /package/dist/views/{Tools → Steps}/FlowChart/layout.d.ts +0 -0
- /package/dist/views/{Tools → Steps}/FlowChart/layout.js +0 -0
- /package/dist/views/{Tools → Steps}/FlowChart/styled.d.ts +0 -0
- /package/dist/views/{Tools → Steps}/FlowChart/types.js +0 -0
- /package/dist/views/{Tools → Steps}/utils.js +0 -0
- /package/src/views/{Tools → Steps}/FlowChart/HandleGroup.tsx +0 -0
- /package/src/views/{Tools → Steps}/FlowChart/layout.ts +0 -0
package/src/index.ts
CHANGED
|
@@ -11,5 +11,5 @@ export { ChatState } from './state/ChatState'
|
|
|
11
11
|
export type { MessageInterceptor } from './state/ChatState'
|
|
12
12
|
export { ChatTabsController } from './state/ChatTabsController'
|
|
13
13
|
export { ObservableState } from './state/ObservableState'
|
|
14
|
-
export type { Labeled,
|
|
14
|
+
export type { Labeled, LabeledAgent } from './state/types'
|
|
15
15
|
export { WidgetState } from './state/WidgetState'
|
package/src/state/ChatEntry.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { OneOfColorSchemes } from '@citric/core'
|
|
2
|
+
import { ChatStep } from '@stack-spot/portal-network'
|
|
2
3
|
import { ColorPaletteName } from '@stack-spot/portal-theme'
|
|
3
4
|
import { pull } from 'lodash'
|
|
4
|
-
import {
|
|
5
|
+
import { LabeledAgent } from './types'
|
|
5
6
|
|
|
6
7
|
export interface ActionDataClick {
|
|
7
8
|
name?: string,
|
|
@@ -57,24 +58,11 @@ export interface KnowledgeSource {
|
|
|
57
58
|
documentId: string,
|
|
58
59
|
}
|
|
59
60
|
|
|
60
|
-
export interface
|
|
61
|
+
export interface ChatTool {
|
|
61
62
|
id: string,
|
|
62
|
-
name: string,
|
|
63
|
-
description?: string,
|
|
64
63
|
image?: string,
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
output?: string,
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export interface ChatEntryStep {
|
|
71
|
-
id: string,
|
|
72
|
-
type: 'planning' | 'step' | 'answer',
|
|
73
|
-
input?: string,
|
|
74
|
-
output?: string,
|
|
75
|
-
status: 'pending' | 'running' | 'success' | 'error',
|
|
76
|
-
duration?: number,
|
|
77
|
-
tools?: AgentTool[],
|
|
64
|
+
name: string,
|
|
65
|
+
description: string,
|
|
78
66
|
}
|
|
79
67
|
|
|
80
68
|
export interface TextChatEntry {
|
|
@@ -109,9 +97,9 @@ export interface TextChatEntry {
|
|
|
109
97
|
*/
|
|
110
98
|
updated?: string,
|
|
111
99
|
/**
|
|
112
|
-
* The agent who wrote the message. Undefined for the
|
|
100
|
+
* The agent who wrote the message. Undefined for the agentType is "user".
|
|
113
101
|
*/
|
|
114
|
-
agent?:
|
|
102
|
+
agent?: LabeledAgent,
|
|
115
103
|
/**
|
|
116
104
|
* The unique identifier of the message.
|
|
117
105
|
*/
|
|
@@ -131,7 +119,11 @@ export interface TextChatEntry {
|
|
|
131
119
|
/**
|
|
132
120
|
* This entry may contain steps. If so, specify them in this array.
|
|
133
121
|
*/
|
|
134
|
-
steps?:
|
|
122
|
+
steps?: ChatStep[],
|
|
123
|
+
/**
|
|
124
|
+
* If any tool was used to generate the response, its id is returned in this list.
|
|
125
|
+
*/
|
|
126
|
+
tools?: string[],
|
|
135
127
|
/*
|
|
136
128
|
* Options for radio, checkbox or button type.
|
|
137
129
|
*/
|
package/src/state/ChatState.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { AbortedError } from '../AbortedError'
|
|
|
4
4
|
import { ChatFeatures, getFeaturesWithDefaults } from '../features'
|
|
5
5
|
import { ChatEntry } from './ChatEntry'
|
|
6
6
|
import { ObservableState } from './ObservableState'
|
|
7
|
-
import { Labeled,
|
|
7
|
+
import { Labeled, LabeledAgent } from './types'
|
|
8
8
|
|
|
9
9
|
export interface ChatPropertiesWithOptionalFeatures {
|
|
10
10
|
/**
|
|
@@ -14,7 +14,7 @@ export interface ChatPropertiesWithOptionalFeatures {
|
|
|
14
14
|
/**
|
|
15
15
|
* The current AI agent.
|
|
16
16
|
*/
|
|
17
|
-
agent?:
|
|
17
|
+
agent?: LabeledAgent,
|
|
18
18
|
/**
|
|
19
19
|
* The current workspace.
|
|
20
20
|
*/
|
package/src/state/WidgetState.ts
CHANGED
|
@@ -13,15 +13,15 @@ export interface WidgetProperties {
|
|
|
13
13
|
/**
|
|
14
14
|
* Current content of the right panel. Undefined for closed right panel.
|
|
15
15
|
*/
|
|
16
|
-
panel?: 'stack' | 'workspace' | 'agent' | 'ks' | 'editor' | 'history' | 'ks-details' | 'tools',
|
|
16
|
+
panel?: 'stack' | 'workspace' | 'agent' | 'ks' | 'editor' | 'history' | 'ks-details' | 'steps' | 'tools',
|
|
17
17
|
/**
|
|
18
18
|
* KS to use when the right panel "ks-details" is open.
|
|
19
19
|
*/
|
|
20
20
|
currentKSInPanel?: { name: string, slug: string, score: number, documentId: string },
|
|
21
21
|
/**
|
|
22
|
-
* The message to show in the tools panel.
|
|
22
|
+
* The message to show in the tools panel or the steps panel.
|
|
23
23
|
*/
|
|
24
|
-
|
|
24
|
+
currentMessageInPanel?: { chatId: string, messageId: number },
|
|
25
25
|
/**
|
|
26
26
|
* Whether or not the widget is in its minimized version.
|
|
27
27
|
*/
|
|
@@ -58,8 +58,6 @@ interface Options {
|
|
|
58
58
|
chatTabs?: ChatTabsController,
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
const untitledChatPrefix = 'Chat '
|
|
62
|
-
|
|
63
61
|
/**
|
|
64
62
|
* Holds the full state of the AI Chat Widget.
|
|
65
63
|
*
|
|
@@ -90,16 +88,6 @@ export class WidgetState extends ObservableState<WidgetProperties> {
|
|
|
90
88
|
this.createChat()
|
|
91
89
|
}
|
|
92
90
|
|
|
93
|
-
private getNextUntitledChatIndex() {
|
|
94
|
-
let max = 0
|
|
95
|
-
for (const chat of this.chatTabs.getAll()) {
|
|
96
|
-
const [, match] = chat.get('label').match(`${untitledChatPrefix}(\\d+)`) ?? []
|
|
97
|
-
const index = parseInt(match)
|
|
98
|
-
if (index > max) max = index
|
|
99
|
-
}
|
|
100
|
-
return max + 1
|
|
101
|
-
}
|
|
102
|
-
|
|
103
91
|
/**
|
|
104
92
|
* Utility function for adding a new chat to the chat tabs. This also selects the new tab.
|
|
105
93
|
* @param properties the chat properties (initial state).
|
|
@@ -109,7 +97,7 @@ export class WidgetState extends ObservableState<WidgetProperties> {
|
|
|
109
97
|
createChat({ label, ...properties }: Partial<ChatPropertiesWithOptionalFeatures> = {}, entries: ChatEntry[] = []) {
|
|
110
98
|
const chat = new ChatState({
|
|
111
99
|
id: ulid(),
|
|
112
|
-
initial: { label: label ||
|
|
100
|
+
initial: { label: label || 'Chat', features: this.chatFeatures, ...properties },
|
|
113
101
|
entries,
|
|
114
102
|
interceptors: this.interceptors,
|
|
115
103
|
untitled: !label,
|
package/src/state/types.ts
CHANGED
package/src/utils/agent.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const isAgentDefault = (agentSlug?: string) => agentSlug === 'stk_code_buddy'
|
|
1
|
+
export const isAgentDefault = (agentSlug?: string) => agentSlug === 'stk_code_buddy'
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BuiltinToolResponse, ToolkitsInAgentResponse } from '@stack-spot/portal-network/api/agent'
|
|
2
|
+
|
|
3
|
+
export type ToolWithImage = BuiltinToolResponse & { id: string, image?: string }
|
|
4
|
+
|
|
5
|
+
export function toolById(id: string, toolkits: ToolkitsInAgentResponse | undefined): ToolWithImage | undefined {
|
|
6
|
+
for (const toolkit of toolkits?.builtins ?? []) {
|
|
7
|
+
for (const tool of toolkit.tools ?? []) {
|
|
8
|
+
if (tool.id === id) return { ...tool, id, image: toolkit.image_url }
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -2,6 +2,7 @@ import { Text } from '@citric/core'
|
|
|
2
2
|
import { Badge, Skeleton } from '@citric/ui'
|
|
3
3
|
import { agentClient } from '@stack-spot/portal-network'
|
|
4
4
|
import { useMemo } from 'react'
|
|
5
|
+
import { ToolBadge } from '../../components/ToolBadge'
|
|
5
6
|
import { useAgentsDictionary } from './dictionary'
|
|
6
7
|
import { AgentDescriptionBox } from './styled'
|
|
7
8
|
|
|
@@ -28,6 +29,15 @@ export const AgentDescription = ({ agentId, llm, description, numberOfKnowledgeS
|
|
|
28
29
|
}
|
|
29
30
|
return loadingKS
|
|
30
31
|
}, [numberOfKnowledgeSources])
|
|
32
|
+
const tools = useMemo(() => {
|
|
33
|
+
const result: React.ReactElement[] = []
|
|
34
|
+
for (const kit of agent?.toolkits?.builtins ?? []) {
|
|
35
|
+
for (const tool of kit.tools ?? []) {
|
|
36
|
+
result.push(<li key={tool.id}><ToolBadge name={tool.name || tool.id || 'unknown'} image={kit.image_url} /></li>)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return result
|
|
40
|
+
}, [agent])
|
|
31
41
|
|
|
32
42
|
return (
|
|
33
43
|
<AgentDescriptionBox>
|
|
@@ -39,6 +49,10 @@ export const AgentDescription = ({ agentId, llm, description, numberOfKnowledgeS
|
|
|
39
49
|
<Text appearance="microtext1" className="title">Knowledge sources</Text>
|
|
40
50
|
<ul>{isLoading ? skeleton : knowledgeSources}</ul>
|
|
41
51
|
</section>}
|
|
52
|
+
{!!tools.length && <section>
|
|
53
|
+
<Text appearance="microtext1" className="title">{t.tools}</Text>
|
|
54
|
+
<ul>{tools}</ul>
|
|
55
|
+
</section>}
|
|
42
56
|
{llm && <section>
|
|
43
57
|
<Text appearance="microtext1" className="title">LLM</Text>
|
|
44
58
|
<Badge palette="orange" appearance="square">{llm}</Badge>
|
|
@@ -20,24 +20,19 @@ export const AgentsTab = ({ visibility }: { visibility: VisibilityLevel | 'BUILT
|
|
|
20
20
|
const chat = useCurrentChat()
|
|
21
21
|
const [filter, setFilter] = useState('')
|
|
22
22
|
const agentsBuiltIn = agentClient.publicAgents.useQuery({})
|
|
23
|
-
const
|
|
23
|
+
const agentDefault = agentsBuiltIn.find((agent) => isAgentDefault(agent.slug))
|
|
24
24
|
const agents = visibility === 'BUILT-IN' ? agentsBuiltIn : agentClient.agents.useQuery({ visibility })
|
|
25
25
|
const [value, setValue] = useState<AgentResponse | undefined>(
|
|
26
|
-
chat.get('agent') ? agents.find(a => a.id === chat.get('agent')?.id) :
|
|
26
|
+
chat.get('agent') ? agents.find(a => a.id === chat.get('agent')?.id) : agentDefault,
|
|
27
27
|
)
|
|
28
28
|
const filtered = useMemo(
|
|
29
|
-
() =>
|
|
30
|
-
return filter ? agents.filter(a => a === value || a.name.toLocaleLowerCase().includes(filter.toLocaleLowerCase())) : agents
|
|
31
|
-
},
|
|
29
|
+
() => filter ? agents.filter(a => a === value || a.name.toLocaleLowerCase().includes(filter.toLocaleLowerCase())) : agents,
|
|
32
30
|
[agents, filter, value],
|
|
33
31
|
)
|
|
34
32
|
|
|
35
33
|
function submit() {
|
|
36
34
|
if (value) {
|
|
37
|
-
chat.set('agent',
|
|
38
|
-
? { id: value.id, label: value.name, image: value.avatar, builtIn: visibility === 'BUILT-IN', slug: value.slug }
|
|
39
|
-
: undefined
|
|
40
|
-
)
|
|
35
|
+
chat.set('agent', { id: value.id, label: value.name, image: value.avatar, builtIn: visibility === 'BUILT-IN', slug: value.slug })
|
|
41
36
|
}
|
|
42
37
|
close()
|
|
43
38
|
}
|
|
@@ -53,7 +48,7 @@ export const AgentsTab = ({ visibility }: { visibility: VisibilityLevel | 'BUILT
|
|
|
53
48
|
onChange={setValue}
|
|
54
49
|
renderLabel={({ name, avatar, id }) => (
|
|
55
50
|
<AgentLabel>
|
|
56
|
-
{id ? (avatar ? <img src={avatar} /> :
|
|
51
|
+
{id ? (avatar ? <img src={avatar} /> : <IconBox size="xs"><Agent /></IconBox>) : <MiniLogo />}
|
|
57
52
|
<Text>{name}</Text>
|
|
58
53
|
</AgentLabel>
|
|
59
54
|
)}
|
|
@@ -15,6 +15,7 @@ const dictionary = {
|
|
|
15
15
|
noDataDescription: 'Use the tabs above to try other categories or use the AI portal to create new agents.',
|
|
16
16
|
defaultAgentDescription: 'The StackSpot CodeGen is an advanced artificial intelligence agent designed to optimize and accelerate software development. Integrated directly into your integrated development environment, StackSpot CodeGen offers real-time code suggestions, helping developers write high-quality code more efficiently. With robust features such as creating Stacks AI, customized knowledge sources, and quick commands, StackSpot CodeGen contextualizes your development needs to provide the best answers and code suggestions.',
|
|
17
17
|
description: 'Description',
|
|
18
|
+
tools: 'Tools',
|
|
18
19
|
},
|
|
19
20
|
pt: {
|
|
20
21
|
title: 'Agentes',
|
|
@@ -30,6 +31,7 @@ const dictionary = {
|
|
|
30
31
|
noDataDescription: 'Use as abas acima para tentar outras categorias ou use o Portal AI para criar novos agentes.',
|
|
31
32
|
defaultAgentDescription: 'O StackSpot CodeGen é um agente de inteligência artificial avançado projetado para otimizar e acelerar o desenvolvimento de software. Integrado diretamente ao seu ambiente de desenvolvimento, o StackSpot CodeGen oferece sugestões de código em tempo real, ajudando os desenvolvedores a escreverem código de alta qualidade de forma mais eficiente. Com recursos robustos, como a criação de Stacks AI, Knowledge Sources personalizadas e comandos rápidos, o StackSpot CodeGen contextualiza suas necessidades de desenvolvimento para fornecer as melhores respostas e sugestões de código.',
|
|
32
33
|
description: 'Descrição',
|
|
34
|
+
tools: 'Ferramentas',
|
|
33
35
|
},
|
|
34
36
|
} satisfies Dictionary
|
|
35
37
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Text } from '@citric/core'
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { IconBox, Text } from '@citric/core'
|
|
2
|
+
import { Agent } from '@citric/icons'
|
|
3
|
+
import { LabeledAgent } from '../../state/types'
|
|
4
4
|
|
|
5
5
|
interface Props {
|
|
6
|
-
agent?:
|
|
6
|
+
agent?: LabeledAgent,
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -13,8 +13,8 @@ export const AgentInfo = ({ agent }: Props) => (
|
|
|
13
13
|
<>
|
|
14
14
|
{agent?.image
|
|
15
15
|
? <img src={agent.image} className="custom-agent-image" />
|
|
16
|
-
: <
|
|
16
|
+
: <IconBox className="default-image-wrapper" colorIcon="light.700"><Agent className="agent-image" /></IconBox>
|
|
17
17
|
}
|
|
18
|
-
<Text appearance="body2">{agent?.label
|
|
18
|
+
<Text appearance="body2">{agent?.label}</Text>
|
|
19
19
|
</>
|
|
20
20
|
)
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/* eslint-disable semi */
|
|
2
2
|
import { Box, Button, Checkbox, Flex, IconBox, Input, Label, Radio, Text } from '@citric/core'
|
|
3
|
-
import { Copy, Dislike, DislikeFill, Like, LikeFill, TimesCircle } from '@citric/icons'
|
|
3
|
+
import { Cog, Copy, Dislike, DislikeFill, Like, LikeFill, TimesCircle } from '@citric/icons'
|
|
4
4
|
import { Avatar, Badge, IconButton } from '@citric/ui'
|
|
5
|
+
import { agentClient } from '@stack-spot/portal-network'
|
|
5
6
|
import { listToClass } from '@stack-spot/portal-theme'
|
|
6
7
|
import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
|
|
7
8
|
import { debounce } from 'lodash'
|
|
@@ -9,9 +10,11 @@ import { Dispatch, useCallback, useEffect, useMemo, useRef, useState } from 'rea
|
|
|
9
10
|
import { PhoneInput } from 'react-international-phone'
|
|
10
11
|
import 'react-international-phone/style.css'
|
|
11
12
|
import { Markdown } from '../../components/Markdown'
|
|
13
|
+
import { StackedBadge } from '../../components/StackedBadge'
|
|
12
14
|
import { useChatEntry, useCurrentChat, useWidget } from '../../context/hooks'
|
|
13
15
|
import { ChatEntry, SerializableAction, TextChatEntry } from '../../state/ChatEntry'
|
|
14
16
|
import { useDateFormatter } from '../../utils/date'
|
|
17
|
+
import { toolById } from '../../utils/tools'
|
|
15
18
|
import { AgentInfo } from './AgentInfo'
|
|
16
19
|
import { useChatScrollToBottomEffect } from './chat-scroll'
|
|
17
20
|
import { onCopyAll, onCopyCode, onLikeOrDislike } from './events'
|
|
@@ -82,7 +85,7 @@ const RenderInputsEntry = ({ isLast, entry, value, setValue, labels, setLabels }
|
|
|
82
85
|
{option.hasInput && option.value && labels.findIndex((label) => label === option.value) !== -1 &&
|
|
83
86
|
<Box w={4} ml={2}>
|
|
84
87
|
<Input name={entry.name} onChange={(data) => setValue([data.target.value])}
|
|
85
|
-
required={true} />
|
|
88
|
+
required={true} sx={{ height: '30px' }} />
|
|
86
89
|
</Box>
|
|
87
90
|
}
|
|
88
91
|
</Flex>
|
|
@@ -120,7 +123,7 @@ const RenderInputsEntry = ({ isLast, entry, value, setValue, labels, setLabels }
|
|
|
120
123
|
{option.hasInput && option.value && labels.findIndex((label) => label === option.value)!== -1 &&
|
|
121
124
|
<Box w={4} ml={2}>
|
|
122
125
|
<Input name={entry.name} {...entry.validations} onChange={(data) => handleChange(data)}
|
|
123
|
-
required={true}
|
|
126
|
+
required={true} sx={{ height: '30px' }} />
|
|
124
127
|
</Box>
|
|
125
128
|
}
|
|
126
129
|
</Flex>
|
|
@@ -163,6 +166,11 @@ export const ChatMessage = ({ message, username, isLast }: Props) => {
|
|
|
163
166
|
const chatRef = useRef<HTMLDivElement>(null)
|
|
164
167
|
const widget = useWidget()
|
|
165
168
|
const chat = useCurrentChat()
|
|
169
|
+
const agentId = entry.agent?.id ?? ''
|
|
170
|
+
const [agentById] = agentClient.agent.useStatefulQuery({ agentId }, { enabled: !!agentId && !entry?.agent?.builtIn })
|
|
171
|
+
const [AgentBuiltInById] = agentClient.publicAgent.useStatefulQuery({ agentId }, { enabled: !!agentId && entry?.agent?.builtIn })
|
|
172
|
+
const agent = agentById ?? AgentBuiltInById
|
|
173
|
+
|
|
166
174
|
useChatScrollToBottomEffect(ref, [entry])
|
|
167
175
|
|
|
168
176
|
const detailKS = useCallback(({ name, slug, documentScore, documentId }: Required<TextChatEntry>['knowledgeSources'][number]) => {
|
|
@@ -249,10 +257,15 @@ export const ChatMessage = ({ message, username, isLast }: Props) => {
|
|
|
249
257
|
</form>
|
|
250
258
|
}
|
|
251
259
|
|
|
260
|
+
function openToolsPanel() {
|
|
261
|
+
widget.set('currentMessageInPanel', { chatId: chat.id, messageId: message.id })
|
|
262
|
+
widget.set('panel', 'tools')
|
|
263
|
+
}
|
|
264
|
+
|
|
252
265
|
return (entry.content || entry.error || !!entry.steps?.length) && (
|
|
253
266
|
<li className={entry.agentType} ref={ref}>
|
|
254
267
|
<div className="chat-message" ref={chatRef} onKeyDown={handleKeyDown} tabIndex={0}>
|
|
255
|
-
<div className=
|
|
268
|
+
<div className={`user-info ${entry.agentType}`}>{userInfo}</div>
|
|
256
269
|
{(entry.content || entry.steps) && <div className={listToClass(['message-content', entry.card && 'card'])}>
|
|
257
270
|
{!!entry.badges?.length && <div className="badges">
|
|
258
271
|
{entry.badges.map((b, index) => <Badge key={index} palette={b.color ?? 'cyan'} appearance="square">{b.label}</Badge>)}
|
|
@@ -268,6 +281,19 @@ export const ChatMessage = ({ message, username, isLast }: Props) => {
|
|
|
268
281
|
<Text appearance="microtext1">{entry.error}</Text>
|
|
269
282
|
</div>
|
|
270
283
|
)}
|
|
284
|
+
{!!entry.tools?.length && <StackedBadge
|
|
285
|
+
aria-label={t.openToolsPanel}
|
|
286
|
+
title={t.openToolsPanel}
|
|
287
|
+
tabIndex={0}
|
|
288
|
+
role="button"
|
|
289
|
+
className="tools-badge"
|
|
290
|
+
label={t.tools}
|
|
291
|
+
images={entry.tools.slice(0, 3).map((id) => {
|
|
292
|
+
const tool = toolById(id, agent?.toolkits)
|
|
293
|
+
return { key: id, name: tool?.name || id, icon: <Cog />, url: tool?.image }
|
|
294
|
+
})}
|
|
295
|
+
onClick={openToolsPanel}
|
|
296
|
+
/>}
|
|
271
297
|
{!!entry.knowledgeSources?.length && <div className="ks-box">
|
|
272
298
|
<Text appearance="microtext1" colorScheme="light.700">Knowledge Sources:</Text>
|
|
273
299
|
<ul>{entry.knowledgeSources.map((ks, index) => (
|
|
@@ -307,10 +333,14 @@ const dictionary = {
|
|
|
307
333
|
copy: 'Copy',
|
|
308
334
|
like: 'Like',
|
|
309
335
|
dislike: 'Dislike',
|
|
336
|
+
tools: 'Tools',
|
|
337
|
+
openToolsPanel: 'Open the tools panel to see more details.',
|
|
310
338
|
},
|
|
311
339
|
pt: {
|
|
312
340
|
copy: 'Copiar',
|
|
313
341
|
like: 'Gostei',
|
|
314
342
|
dislike: 'Não gostei',
|
|
343
|
+
tools: 'Ferramentas',
|
|
344
|
+
openToolsPanel: 'Abrir o painel de ferramentas para ver mais detalhes.',
|
|
315
345
|
},
|
|
316
346
|
} satisfies Dictionary
|
|
@@ -2,27 +2,27 @@ import { Button, IconBox, Text } from '@citric/core'
|
|
|
2
2
|
import { CheckCircleFill, Circle, PlayFill, TimesCircleFill } from '@citric/icons'
|
|
3
3
|
import { LoadingCircular } from '@citric/ui'
|
|
4
4
|
import { AnimatedHeight } from '@stack-spot/portal-components/AnimatedHeight'
|
|
5
|
+
import { ChatStep, StepChatStep } from '@stack-spot/portal-network'
|
|
5
6
|
import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
|
|
6
7
|
import { findLastIndex } from 'lodash'
|
|
7
8
|
import { useState } from 'react'
|
|
8
9
|
import { useWidget } from '../../context/hooks'
|
|
9
|
-
import { ChatEntryStep } from '../../state/ChatEntry'
|
|
10
10
|
import { PropsOf } from '../../types'
|
|
11
11
|
|
|
12
12
|
interface Props {
|
|
13
|
-
steps:
|
|
13
|
+
steps: ChatStep[],
|
|
14
14
|
messageId: number,
|
|
15
15
|
chatId: string,
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
interface StepProps {
|
|
19
|
-
step:
|
|
19
|
+
step: StepChatStep,
|
|
20
20
|
index: number,
|
|
21
21
|
total: number,
|
|
22
22
|
onClick?: () => void,
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
function getStatusIcon(status:
|
|
25
|
+
function getStatusIcon(status: ChatStep['status']) {
|
|
26
26
|
const iconBoxProps: PropsOf<typeof IconBox> = { colorIcon: 'light.700', size: 'xs' }
|
|
27
27
|
switch (status) {
|
|
28
28
|
case 'error': return <IconBox {...iconBoxProps}><TimesCircleFill /></IconBox>
|
|
@@ -53,8 +53,8 @@ export const StepsList = ({ steps, chatId, messageId }: Props) => {
|
|
|
53
53
|
const widget = useWidget()
|
|
54
54
|
|
|
55
55
|
function openToolsPanel() {
|
|
56
|
-
widget.set('
|
|
57
|
-
widget.set('panel', '
|
|
56
|
+
widget.set('currentMessageInPanel', { chatId, messageId })
|
|
57
|
+
widget.set('panel', 'steps')
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
return (
|
package/src/views/Chat/styled.ts
CHANGED
|
@@ -38,6 +38,10 @@ export const ChatList: IStyledComponentBase<
|
|
|
38
38
|
display: flex;
|
|
39
39
|
flex-direction: row;
|
|
40
40
|
gap: 10px;
|
|
41
|
+
|
|
42
|
+
&.bot {
|
|
43
|
+
align-items: center;
|
|
44
|
+
}
|
|
41
45
|
}
|
|
42
46
|
|
|
43
47
|
.chat-message {
|
|
@@ -82,23 +86,19 @@ export const ChatList: IStyledComponentBase<
|
|
|
82
86
|
gap: 4px;
|
|
83
87
|
|
|
84
88
|
.default-image-wrapper {
|
|
85
|
-
width:
|
|
86
|
-
height:
|
|
87
|
-
border-radius:
|
|
89
|
+
width: 32px;
|
|
90
|
+
height: 32px;
|
|
91
|
+
border-radius: 50%;
|
|
88
92
|
background-color: ${theme.color.light[300]};
|
|
89
93
|
display: flex;
|
|
90
94
|
align-items: center;
|
|
91
95
|
justify-content: center;
|
|
92
|
-
|
|
93
|
-
.agent-image {
|
|
94
|
-
width: 18px;
|
|
95
|
-
height: 18px;
|
|
96
|
-
}
|
|
96
|
+
border: 1px solid ${theme.color.light[600]};
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
.custom-agent-image {
|
|
100
|
-
width:
|
|
101
|
-
height:
|
|
100
|
+
width: 32px;
|
|
101
|
+
height: 32px;
|
|
102
102
|
border-radius: 50%;
|
|
103
103
|
}
|
|
104
104
|
}
|
|
@@ -149,11 +149,11 @@ export const ChatList: IStyledComponentBase<
|
|
|
149
149
|
background-color: ${theme.color.light[500]};
|
|
150
150
|
border-radius: 4px;
|
|
151
151
|
|
|
152
|
-
> p:first-child {
|
|
152
|
+
.markdown > p:first-child {
|
|
153
153
|
margin-top: 0;
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
> p:last-child {
|
|
156
|
+
.markdown > p:last-child {
|
|
157
157
|
margin-bottom: 0;
|
|
158
158
|
}
|
|
159
159
|
}
|
|
@@ -244,4 +244,13 @@ export const ChatList: IStyledComponentBase<
|
|
|
244
244
|
}
|
|
245
245
|
}
|
|
246
246
|
}
|
|
247
|
+
|
|
248
|
+
.markdown img {
|
|
249
|
+
max-width: 70%;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.tools-badge {
|
|
253
|
+
align-self: start;
|
|
254
|
+
cursor: pointer;
|
|
255
|
+
}
|
|
247
256
|
`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { agentClient, aiClient, workspaceClient } from '@stack-spot/portal-network'
|
|
2
2
|
import { ChatProperties } from '../../state/ChatState'
|
|
3
|
-
import {
|
|
3
|
+
import { LabeledAgent } from '../../state/types'
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Finds a stack by its id.
|
|
@@ -40,7 +40,7 @@ export async function findWorkspace(id: string | null): Promise<ChatProperties['
|
|
|
40
40
|
* Finds all the agents, including common agents and public agents.
|
|
41
41
|
* @returns an array with every agent.
|
|
42
42
|
*/
|
|
43
|
-
export async function getAllAgents(): Promise<
|
|
43
|
+
export async function getAllAgents(): Promise<LabeledAgent[]> {
|
|
44
44
|
try {
|
|
45
45
|
const [agents, publicAgents] = await Promise.all([agentClient.agents.query({}), agentClient.publicAgents.query({})])
|
|
46
46
|
return [...agents, ...publicAgents].map(a => ({ id: a.id, label: a.name, image: a.avatar }))
|
|
@@ -3,6 +3,8 @@ import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
|
|
|
3
3
|
import { useMemo } from 'react'
|
|
4
4
|
import { TabManager } from '../components/TabManager'
|
|
5
5
|
import { useChatState, useChatTabs, useWidget, useWidgetState } from '../context/hooks'
|
|
6
|
+
import { useRightPanel } from '../right-panel/hooks'
|
|
7
|
+
import { ChatState } from '../state/ChatState'
|
|
6
8
|
import { ButtonAction } from '../types'
|
|
7
9
|
|
|
8
10
|
const TabLabel = ({ id }: { id: string }) => {
|
|
@@ -18,13 +20,29 @@ export const ChatTabSelection = () => {
|
|
|
18
20
|
const widget = useWidget()
|
|
19
21
|
const { chatHistory } = useWidgetState('features') ?? {}
|
|
20
22
|
const { active, chats } = useChatTabs()
|
|
23
|
+
const { close: closeRightPanel } = useRightPanel()
|
|
24
|
+
|
|
25
|
+
function create() {
|
|
26
|
+
widget.createChat()
|
|
27
|
+
closeRightPanel()
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function select({ id }: ChatState) {
|
|
31
|
+
widget.chatTabs.select(id)
|
|
32
|
+
closeRightPanel()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function remove({ id }: ChatState) {
|
|
36
|
+
widget.chatTabs.remove(id)
|
|
37
|
+
closeRightPanel()
|
|
38
|
+
}
|
|
21
39
|
|
|
22
40
|
const buttons = useMemo<ButtonAction[]>(
|
|
23
41
|
() => {
|
|
24
42
|
const actions: ButtonAction[] = [{
|
|
25
43
|
icon: <Plus />,
|
|
26
44
|
label: t.newChat,
|
|
27
|
-
onClick:
|
|
45
|
+
onClick: create,
|
|
28
46
|
}]
|
|
29
47
|
if (chatHistory) {
|
|
30
48
|
actions.push({
|
|
@@ -39,14 +57,14 @@ export const ChatTabSelection = () => {
|
|
|
39
57
|
},
|
|
40
58
|
[chatHistory],
|
|
41
59
|
)
|
|
42
|
-
|
|
60
|
+
|
|
43
61
|
return <TabManager
|
|
44
62
|
tabs={chats}
|
|
45
63
|
active={active.id}
|
|
46
64
|
renderLabel={({ id }) => <TabLabel id={id} />}
|
|
47
65
|
keygen={({ id }) => id}
|
|
48
|
-
onRemove={
|
|
49
|
-
onSelect={
|
|
66
|
+
onRemove={remove}
|
|
67
|
+
onSelect={select}
|
|
50
68
|
buttons={buttons}
|
|
51
69
|
/>
|
|
52
70
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Flex, IconBox, Image } from '@citric/core'
|
|
2
2
|
import { Agent } from '@citric/icons'
|
|
3
|
-
import { MiniLogo } from '@stack-spot/portal-components/svg'
|
|
4
3
|
import { agentClient } from '@stack-spot/portal-network'
|
|
5
4
|
import { AgentResponse } from '@stack-spot/portal-network/api/agent'
|
|
6
5
|
import { uniqBy } from 'lodash'
|
|
@@ -8,7 +7,6 @@ import { useCallback } from 'react'
|
|
|
8
7
|
import { Selector } from '../../components/Selector'
|
|
9
8
|
import { useCurrentChat, useCurrentChatState } from '../../context/hooks'
|
|
10
9
|
import { agentRegex } from '../../regex'
|
|
11
|
-
import { isAgentDefault } from '../../utils/agent'
|
|
12
10
|
|
|
13
11
|
export const AgentSelector = ({ inputRef }: { inputRef: React.RefObject<HTMLTextAreaElement | HTMLInputElement> }) => {
|
|
14
12
|
const chat = useCurrentChat()
|
|
@@ -16,9 +14,9 @@ export const AgentSelector = ({ inputRef }: { inputRef: React.RefObject<HTMLText
|
|
|
16
14
|
const onSelectItem = useCallback((agent: AgentResponse) => {
|
|
17
15
|
const newValue = `@${agent.slug}`
|
|
18
16
|
chat.set('nextMessage', undefined)
|
|
19
|
-
chat.set(
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
chat.set(
|
|
18
|
+
'agent',
|
|
19
|
+
{ id: agent.id, label: agent.name, image: agent.avatar, slug: agent.slug, builtIn: agent.visibility_level === 'builtIn' },
|
|
22
20
|
)
|
|
23
21
|
|
|
24
22
|
if (!inputRef.current) return
|
|
@@ -31,16 +29,16 @@ export const AgentSelector = ({ inputRef }: { inputRef: React.RefObject<HTMLText
|
|
|
31
29
|
const accountAgents = agentClient.agents.useQuery({ visibility: 'ACCOUNT' })
|
|
32
30
|
const sharedAgents = agentClient.agents.useQuery({ visibility: 'SHARED' })
|
|
33
31
|
const publicAgents = agentClient.publicAgents.useQuery({})
|
|
34
|
-
const
|
|
32
|
+
const builtIns = [...publicAgents.map((agent) => ({ ...agent, visibility_level: 'builtIn' }))]
|
|
35
33
|
|
|
36
|
-
return uniqBy([...personalAgents, ...accountAgents, ...sharedAgents, ...
|
|
34
|
+
return uniqBy([...personalAgents, ...accountAgents, ...sharedAgents, ...builtIns], 'id')
|
|
37
35
|
}
|
|
38
36
|
|
|
39
|
-
const AgentItem = ({ avatar, name
|
|
37
|
+
const AgentItem = ({ avatar, name }: AgentResponse) => {
|
|
40
38
|
const AvatarComponent = avatar ? <Image width="32" height="32" radius="full" src={avatar} /> : <IconBox size="md"><Agent /></IconBox>
|
|
41
39
|
|
|
42
40
|
return <Flex flexWrap="nowrap" alignItems="center" sx={{ gap: '8px' }}>
|
|
43
|
-
{
|
|
41
|
+
{AvatarComponent}
|
|
44
42
|
<p className="selector-title">{name}</p>
|
|
45
43
|
</Flex>
|
|
46
44
|
}
|