@stack-spot/ai-chat-widget 1.27.0-beta.0 → 1.27.0-beta.2
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/app-metadata.json +3 -3
- package/dist/chat-interceptors/quick-commands.d.ts.map +1 -1
- package/dist/chat-interceptors/quick-commands.js +12 -0
- package/dist/chat-interceptors/quick-commands.js.map +1 -1
- package/dist/components/AgentCard/dictionary.d.ts +2 -4
- package/dist/components/AgentCard/dictionary.d.ts.map +1 -1
- package/dist/components/AgentCard/dictionary.js +2 -4
- package/dist/components/AgentCard/dictionary.js.map +1 -1
- package/dist/components/Selector/index.d.ts +2 -2
- package/dist/components/Selector/index.d.ts.map +1 -1
- package/dist/components/Selector/index.js +2 -2
- package/dist/components/Selector/index.js.map +1 -1
- package/dist/state/constants.js +2 -2
- package/dist/state/constants.js.map +1 -1
- package/dist/state/types.d.ts +1 -1
- package/dist/state/types.d.ts.map +1 -1
- package/dist/utils/tools.d.ts +2 -2
- package/dist/utils/tools.d.ts.map +1 -1
- package/dist/utils/tools.js +6 -3
- package/dist/utils/tools.js.map +1 -1
- package/dist/views/Agents/AgentDescription.d.ts +9 -2
- package/dist/views/Agents/AgentDescription.d.ts.map +1 -1
- package/dist/views/Agents/AgentDescription.js +9 -11
- package/dist/views/Agents/AgentDescription.js.map +1 -1
- package/dist/views/Agents/AgentsPanel.d.ts.map +1 -1
- package/dist/views/Agents/AgentsPanel.js +11 -11
- package/dist/views/Agents/AgentsPanel.js.map +1 -1
- package/dist/views/Agents/AgentsTab.d.ts +2 -2
- package/dist/views/Agents/AgentsTab.d.ts.map +1 -1
- package/dist/views/Agents/AgentsTab.js +6 -6
- package/dist/views/Agents/AgentsTab.js.map +1 -1
- package/dist/views/Agents/useAgentFavorites.d.ts +1 -1
- package/dist/views/Agents/useAgentFavorites.js +4 -4
- package/dist/views/Agents/useAgentFavorites.js.map +1 -1
- package/dist/views/Chat/ChatMessage.d.ts.map +1 -1
- package/dist/views/Chat/ChatMessage.js +3 -3
- package/dist/views/Chat/ChatMessage.js.map +1 -1
- package/dist/views/ChatHistory/HistoryItem.d.ts.map +1 -1
- package/dist/views/ChatHistory/HistoryItem.js +5 -8
- package/dist/views/ChatHistory/HistoryItem.js.map +1 -1
- package/dist/views/ChatHistory/utils.d.ts +6 -0
- package/dist/views/ChatHistory/utils.d.ts.map +1 -1
- package/dist/views/ChatHistory/utils.js +16 -1
- package/dist/views/ChatHistory/utils.js.map +1 -1
- package/dist/views/Home/BuiltInAgent.js +1 -1
- package/dist/views/Home/BuiltInAgent.js.map +1 -1
- package/dist/views/Home/CustomAgent.js +3 -3
- package/dist/views/Home/CustomAgent.js.map +1 -1
- package/dist/views/MessageInput/AgentSelector.js +4 -4
- package/dist/views/MessageInput/AgentSelector.js.map +1 -1
- package/dist/views/MessageInput/ButtonAgent.js +2 -2
- package/dist/views/MessageInput/ButtonAgent.js.map +1 -1
- package/dist/views/MessageInput/QuickCommandSelector.js +4 -4
- package/dist/views/MessageInput/QuickCommandSelector.js.map +1 -1
- package/dist/views/MessageInput/dictionary.js +1 -1
- package/dist/views/MessageInput/dictionary.js.map +1 -1
- package/dist/views/Tools.js +3 -3
- package/dist/views/Tools.js.map +1 -1
- package/dist/views/Workspaces/WorkspacesTab.js +1 -1
- package/package.json +8 -8
- package/src/app-metadata.json +3 -3
- package/src/chat-interceptors/quick-commands.ts +15 -2
- package/src/components/AgentCard/dictionary.ts +2 -4
- package/src/components/Selector/index.tsx +5 -4
- package/src/state/constants.ts +2 -2
- package/src/state/types.ts +1 -1
- package/src/utils/tools.ts +7 -5
- package/src/views/Agents/AgentDescription.tsx +25 -18
- package/src/views/Agents/AgentsPanel.tsx +12 -11
- package/src/views/Agents/AgentsTab.tsx +17 -12
- package/src/views/Agents/useAgentFavorites.ts +4 -4
- package/src/views/Chat/ChatMessage.tsx +3 -4
- package/src/views/ChatHistory/HistoryItem.tsx +5 -10
- package/src/views/ChatHistory/utils.ts +18 -1
- package/src/views/Home/BuiltInAgent.tsx +1 -1
- package/src/views/Home/CustomAgent.tsx +4 -4
- package/src/views/MessageInput/AgentSelector.tsx +4 -4
- package/src/views/MessageInput/ButtonAgent.tsx +2 -2
- package/src/views/MessageInput/QuickCommandSelector.tsx +4 -4
- package/src/views/MessageInput/dictionary.ts +1 -1
- package/src/views/Tools.tsx +3 -4
- package/src/views/Workspaces/WorkspacesTab.tsx +1 -1
package/package.json
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stack-spot/ai-chat-widget",
|
|
3
|
-
"version": "1.27.0-beta.
|
|
3
|
+
"version": "1.27.0-beta.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "rimraf dist && pnpm generate:metadata && tsc && tsc-esm-fix --target='dist' && cpy src/layout.css dist --flat && cpy src/assets/**/*.png dist/assets",
|
|
9
|
+
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
|
10
|
+
"generate:metadata": "pnpm app-metadata --lockfile ../../pnpm-lock.yaml --path packages/widget"
|
|
11
|
+
},
|
|
7
12
|
"peerDependencies": {
|
|
8
13
|
"@citric/core": "^6.4.0",
|
|
9
14
|
"@stack-spot/portal-components": "^2.22.1",
|
|
10
15
|
"@citric/icons": "^5.13.0",
|
|
11
|
-
"@stack-spot/portal-network": "
|
|
16
|
+
"@stack-spot/portal-network": "^0.143.3",
|
|
12
17
|
"@citric/ui": "^6.10.2",
|
|
13
18
|
"@stack-spot/portal-theme": "^1.0.0",
|
|
14
19
|
"@stack-spot/portal-translate": "^1.1.0",
|
|
@@ -51,10 +56,5 @@
|
|
|
51
56
|
"ulid": "^2.3.0",
|
|
52
57
|
"@xyflow/react": "^12.3.2",
|
|
53
58
|
"@dagrejs/dagre": "^1.1.4"
|
|
54
|
-
},
|
|
55
|
-
"scripts": {
|
|
56
|
-
"build": "rimraf dist && pnpm generate:metadata && tsc && tsc-esm-fix --target='dist' && cpy src/layout.css dist --flat && cpy src/assets/**/*.png dist/assets",
|
|
57
|
-
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
|
58
|
-
"generate:metadata": "pnpm app-metadata --lockfile ../../pnpm-lock.yaml --path packages/widget"
|
|
59
59
|
}
|
|
60
|
-
}
|
|
60
|
+
}
|
package/src/app-metadata.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stack-spot/ai-chat-widget",
|
|
3
|
-
"version": "1.27.0-beta.
|
|
4
|
-
"date": "
|
|
3
|
+
"version": "1.27.0-beta.2",
|
|
4
|
+
"date": "Fri Jun 20 2025 13:47:36 GMT-0300 (Horário Padrão de Brasília)",
|
|
5
5
|
"dependencies": [
|
|
6
6
|
{
|
|
7
7
|
"name": "@stack-spot/app-metadata",
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
},
|
|
114
114
|
{
|
|
115
115
|
"name": "@stack-spot/portal-network",
|
|
116
|
-
"version": "0.
|
|
116
|
+
"version": "0.143.3(@stack-spot/auth@5.3.2)(@stack-spot/opa@2.5.0(@stack-spot/auth@5.3.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@stack-spot/portal-translate@1.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@tanstack/react-query@5.59.16(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)"
|
|
117
117
|
},
|
|
118
118
|
{
|
|
119
119
|
"name": "@stack-spot/portal-theme",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { aiClient, CancelledError, FixedChatRequest, StackspotAPIError } from '@stack-spot/portal-network'
|
|
2
|
-
import { QuickCommandFetchResponseResult, QuickCommandPromptResponse2, QuickCommandResponse } from '@stack-spot/portal-network/api/ai'
|
|
2
|
+
import { QuickCommandFetchResponseResult, QuickCommandPromptResponse2, QuickCommandResponse, QuickCommandStepFetchResponse } from '@stack-spot/portal-network/api/ai'
|
|
3
3
|
import { Dictionary, interpolate, translate } from '@stack-spot/portal-translate'
|
|
4
4
|
import type { editor } from 'monaco-editor'
|
|
5
5
|
import { ulid } from 'ulid'
|
|
@@ -71,7 +71,20 @@ export function createQuickCommandInterceptor(widget: WidgetState, getEditor: ()
|
|
|
71
71
|
*/
|
|
72
72
|
async function runFetchStep(ctx: QCContext, stepIndex: number) {
|
|
73
73
|
const { qc: { slug, steps }, code, context, resultMap, executionId, signal } = ctx
|
|
74
|
-
const step = steps![stepIndex]
|
|
74
|
+
const step = steps![stepIndex] as QuickCommandStepFetchResponse
|
|
75
|
+
if (step.is_remote) {
|
|
76
|
+
const { data } = await aiClient.fetchStepOfQuickCommandRemotely.mutate({
|
|
77
|
+
slug, stepSlug: step.slug,
|
|
78
|
+
quickCommandsExecutionRequest: { code_selection: code, context, slugs_executions: resultMap, qc_execution_id: executionId },
|
|
79
|
+
})
|
|
80
|
+
resultMap[step.slug] = {
|
|
81
|
+
status: 200,
|
|
82
|
+
//@ts-ignore
|
|
83
|
+
data: data,
|
|
84
|
+
}
|
|
85
|
+
return
|
|
86
|
+
}
|
|
87
|
+
|
|
75
88
|
const { headers, data, method, url } = await aiClient.fetchStepOfQuickCommand.mutate({
|
|
76
89
|
slug,
|
|
77
90
|
stepSlug: step.slug,
|
|
@@ -2,8 +2,7 @@ import { Dictionary } from '@stack-spot/portal-translate'
|
|
|
2
2
|
|
|
3
3
|
export const dictionary = {
|
|
4
4
|
en: {
|
|
5
|
-
|
|
6
|
-
workspace: 'Spot',
|
|
5
|
+
builtin: 'Built-in',
|
|
7
6
|
personal: 'Personal',
|
|
8
7
|
account: 'Account',
|
|
9
8
|
shared: 'Shared',
|
|
@@ -11,8 +10,7 @@ export const dictionary = {
|
|
|
11
10
|
create: 'Create',
|
|
12
11
|
},
|
|
13
12
|
pt: {
|
|
14
|
-
|
|
15
|
-
workspace: 'Spot',
|
|
13
|
+
builtin: 'Embutido',
|
|
16
14
|
personal: 'Personal',
|
|
17
15
|
account: 'Conta',
|
|
18
16
|
shared: 'Compartilhado',
|
|
@@ -2,7 +2,7 @@ import { IconBox, Text } from '@citric/core'
|
|
|
2
2
|
import { ExternalLink } from '@citric/icons'
|
|
3
3
|
import { IconButton } from '@citric/ui'
|
|
4
4
|
import { useKeyboardControls } from '@stack-spot/portal-components'
|
|
5
|
-
import {
|
|
5
|
+
import { VisibilityLevelEnum } from '@stack-spot/portal-network/api/ai'
|
|
6
6
|
import { Dictionary, interpolate, useTranslate } from '@stack-spot/portal-translate'
|
|
7
7
|
import React, { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
|
8
8
|
import { useCurrentChatState } from '../../context/hooks'
|
|
@@ -12,7 +12,8 @@ import { Fading } from '../Fading'
|
|
|
12
12
|
import { FallbackBoundary } from '../FallbackBoundary'
|
|
13
13
|
import { SelectorBox } from './styled'
|
|
14
14
|
|
|
15
|
-
type SectionVisibility =
|
|
15
|
+
type SectionVisibility = VisibilityLevelEnum | 'built-in'
|
|
16
|
+
|
|
16
17
|
type SelectorShortcut = '/' | '@'
|
|
17
18
|
|
|
18
19
|
interface Item {
|
|
@@ -267,7 +268,7 @@ const dictionary = {
|
|
|
267
268
|
personal: 'Personal',
|
|
268
269
|
account: 'Account',
|
|
269
270
|
shared: 'Shared',
|
|
270
|
-
'
|
|
271
|
+
'built-in': 'Built-in',
|
|
271
272
|
workspace: 'Spot',
|
|
272
273
|
error: 'Could not load the $0s.',
|
|
273
274
|
noData: 'You don\'t have any $0 yet.',
|
|
@@ -281,7 +282,7 @@ const dictionary = {
|
|
|
281
282
|
account: 'Conta',
|
|
282
283
|
shared: 'Compartilhado',
|
|
283
284
|
workspace: 'Spot',
|
|
284
|
-
'
|
|
285
|
+
'built-in': 'Embutido',
|
|
285
286
|
error: 'Não foi possível carregar os $0s.',
|
|
286
287
|
noData: 'Você ainda não possui $0s.',
|
|
287
288
|
noResults: 'Não $0s para mostrar aqui.',
|
package/src/state/constants.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { FileSize } from './types'
|
|
2
2
|
|
|
3
3
|
export const acceptedFileTypes = [
|
|
4
|
-
'json', 'yaml', 'txt', 'md', 'json', 'yaml', 'pdf', 'xls', 'xlsx', 'csv'
|
|
5
|
-
'go', 'html', 'htm', 'kt', 'kts', 'md', 'php', 'proto', 'py', 'java', 'js', 'jsx', 'ts', 'tsx', 'rst', 'rb', 'rs', 'scala', 'swift',
|
|
4
|
+
'json', 'yaml', 'txt', 'md', 'json', 'yaml', 'pdf', /*'xls', 'xlsx', 'csv',*/ 'cbl', 'cpp', 'cxx', 'cc', 'c', 'hpp', 'hxx', 'hh', 'h',
|
|
5
|
+
'cs', 'go', 'html', 'htm', 'kt', 'kts', 'md', 'php', 'proto', 'py', 'java', 'js', 'jsx', 'ts', 'tsx', 'rst', 'rb', 'rs', 'scala', 'swift',
|
|
6
6
|
'sql', 'yaml', 'yml', 'tf', 'sh', 'ps1', 'psd1', 'psm1', 'bat', 'cmd', 'rego', 'f', 'for', 'r', 'pl', 'vb', 'dart', 'hs', 'lua',
|
|
7
7
|
'asm', 'groovy', 'gvy', 'gy', 'mat', 'clj', 'lisp', 'm', 'cls', 'css', 'scss', 'json', 'jpg', 'jpeg', 'png',
|
|
8
8
|
]
|
package/src/state/types.ts
CHANGED
package/src/utils/tools.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { keyBy } from 'lodash'
|
|
1
|
+
import { BuiltinToolResponse, ToolkitsInAgentResponse } from '@stack-spot/portal-network/api/agent'
|
|
3
2
|
|
|
4
3
|
export type ToolWithImage = BuiltinToolResponse & { id: string, image?: string }
|
|
5
4
|
|
|
6
|
-
export function toolById(id: string, toolkits:
|
|
7
|
-
const
|
|
8
|
-
|
|
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
|
+
}
|
|
9
11
|
}
|
|
@@ -1,21 +1,29 @@
|
|
|
1
1
|
import { Text } from '@citric/core'
|
|
2
2
|
import { Badge, Skeleton } from '@citric/ui'
|
|
3
|
-
import {
|
|
3
|
+
import { agentClient, AgentVisibilityLevel } from '@stack-spot/portal-network'
|
|
4
4
|
import { useMemo } from 'react'
|
|
5
5
|
import { ToolBadge } from '../../components/ToolBadge'
|
|
6
|
-
import { toolById } from '../../utils/tools'
|
|
7
6
|
import { useAgentsDictionary } from './dictionary'
|
|
8
7
|
import { AgentDescriptionBox } from './styled'
|
|
9
8
|
|
|
10
|
-
|
|
9
|
+
interface Props {
|
|
10
|
+
agentId?: string,
|
|
11
|
+
llm?: string,
|
|
12
|
+
description?: string,
|
|
13
|
+
numberOfKnowledgeSources: number,
|
|
14
|
+
visibility: AgentVisibilityLevel,
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const AgentDescription = ({ agentId, llm, description, numberOfKnowledgeSources, visibility }: Props) => {
|
|
11
18
|
const t = useAgentsDictionary()
|
|
12
|
-
const [agent, , , { isLoading }] =
|
|
13
|
-
|
|
14
|
-
|
|
19
|
+
const [agent, , , { isLoading }] = agentClient.agentById.useStatefulQuery(
|
|
20
|
+
{ agentId: agentId!, builtIn: visibility === 'BUILT-IN' },
|
|
21
|
+
{ enabled: !!agentId },
|
|
22
|
+
)
|
|
15
23
|
|
|
16
24
|
const knowledgeSources = useMemo(
|
|
17
|
-
() => agent?.
|
|
18
|
-
<li key={index}><Badge palette="teal" appearance="square">{ks}</Badge></li>
|
|
25
|
+
() => agent?.knowledge_sources_config?.knowledge_sources_details?.map((ks, index) => (
|
|
26
|
+
<li key={index}><Badge palette="teal" appearance="square">{ks.name}</Badge></li>
|
|
19
27
|
)),
|
|
20
28
|
[agent],
|
|
21
29
|
)
|
|
@@ -28,32 +36,31 @@ export const AgentDescription = ({ agentId }: { agentId?: string }) => {
|
|
|
28
36
|
}, [numberOfKnowledgeSources])
|
|
29
37
|
const tools = useMemo(() => {
|
|
30
38
|
const result: React.ReactElement[] = []
|
|
31
|
-
for (const
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
</li>)
|
|
39
|
+
for (const kit of agent?.toolkits?.builtins ?? []) {
|
|
40
|
+
for (const tool of kit.tools ?? []) {
|
|
41
|
+
result.push(<li key={tool.id}><ToolBadge name={tool.name || tool.id || 'unknown'} image={kit.image_url} /></li>)
|
|
42
|
+
}
|
|
36
43
|
}
|
|
37
44
|
return result
|
|
38
45
|
}, [agent])
|
|
39
46
|
|
|
40
47
|
return (
|
|
41
48
|
<AgentDescriptionBox>
|
|
42
|
-
{
|
|
49
|
+
{description && <section>
|
|
43
50
|
<Text appearance="microtext1" className="title">{t.description}</Text>
|
|
44
|
-
<Text>{
|
|
51
|
+
<Text>{description}</Text>
|
|
45
52
|
</section>}
|
|
46
53
|
{(!!numberOfKnowledgeSources || !!knowledgeSources?.length) && <section>
|
|
47
54
|
<Text appearance="microtext1" className="title">Knowledge sources</Text>
|
|
48
|
-
<ul>{isLoading
|
|
55
|
+
<ul>{isLoading ? skeleton : knowledgeSources}</ul>
|
|
49
56
|
</section>}
|
|
50
57
|
{!!tools.length && <section>
|
|
51
58
|
<Text appearance="microtext1" className="title">{t.tools}</Text>
|
|
52
59
|
<ul>{tools}</ul>
|
|
53
60
|
</section>}
|
|
54
|
-
{
|
|
61
|
+
{llm && <section>
|
|
55
62
|
<Text appearance="microtext1" className="title">LLM</Text>
|
|
56
|
-
<Badge palette="orange" appearance="square">{
|
|
63
|
+
<Badge palette="orange" appearance="square">{llm}</Badge>
|
|
57
64
|
</section>}
|
|
58
65
|
</AgentDescriptionBox>
|
|
59
66
|
)
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { agentToolsClient } from '@stack-spot/portal-network'
|
|
2
1
|
import { useEffect, useMemo, useRef } from 'react'
|
|
3
2
|
import { RightPanelTabs } from '../../components/RightPanelTabs'
|
|
4
3
|
import { useCurrentChat } from '../../context/hooks'
|
|
@@ -6,6 +5,8 @@ import { checkIsTrial } from '../../utils/check-is-trial'
|
|
|
6
5
|
import { AgentsTab, AgentsTabWorkspace } from './AgentsTab'
|
|
7
6
|
import { useAgentsDictionary } from './dictionary'
|
|
8
7
|
|
|
8
|
+
const agentDefaultSlug = 'stk_code_buddy'
|
|
9
|
+
|
|
9
10
|
/**
|
|
10
11
|
* Renders the Agent selection form in the Right Panel if this is the panel that is currently opened.
|
|
11
12
|
*/
|
|
@@ -16,22 +17,22 @@ export const AgentsPanel = () => {
|
|
|
16
17
|
const agent = useRef(chat.get('agent'))
|
|
17
18
|
|
|
18
19
|
useEffect(() => {
|
|
19
|
-
if (
|
|
20
|
+
if (agentDefaultSlug !== chat.get('agent')?.slug) {
|
|
20
21
|
agent.current = chat.get('agent')
|
|
21
22
|
}
|
|
22
23
|
}, [chat])
|
|
23
24
|
|
|
24
25
|
const tabs= useMemo(() => isTrial ? [
|
|
25
|
-
{ title: t.favorites, content: <AgentsTab key="favorite" visibility="
|
|
26
|
-
{ title: t.builtin, content: <AgentsTab key="builtin" visibility="
|
|
27
|
-
{ title: t.personal, content: <AgentsTab key="personal" visibility="
|
|
26
|
+
{ title: t.favorites, content: <AgentsTab key="favorite" visibility="FAVORITE" agent={agent} /> },
|
|
27
|
+
{ title: t.builtin, content: <AgentsTab key="builtin" visibility="BUILT-IN" agent={agent} /> },
|
|
28
|
+
{ title: t.personal, content: <AgentsTab key="personal" visibility="PERSONAL" agent={agent} /> },
|
|
28
29
|
]: [
|
|
29
|
-
{ title: t.favorites, content: <AgentsTab key="favorite" visibility="
|
|
30
|
-
{ title: t.builtin, content: <AgentsTab key="builtin" visibility="
|
|
31
|
-
{ title: t.personal, content: <AgentsTab key="personal" visibility="
|
|
32
|
-
{ title: t.shared, content: <AgentsTab key="shared" visibility="
|
|
33
|
-
{ title: t.spots, content: <AgentsTabWorkspace key="workspace" visibility="
|
|
34
|
-
{ title: t.account, content: <AgentsTab key="account" visibility="
|
|
30
|
+
{ title: t.favorites, content: <AgentsTab key="favorite" visibility="FAVORITE" agent={agent} /> },
|
|
31
|
+
{ title: t.builtin, content: <AgentsTab key="builtin" visibility="BUILT-IN" agent={agent} /> },
|
|
32
|
+
{ title: t.personal, content: <AgentsTab key="personal" visibility="PERSONAL" agent={agent} /> },
|
|
33
|
+
{ title: t.shared, content: <AgentsTab key="shared" visibility="SHARED" agent={agent} /> },
|
|
34
|
+
{ title: t.spots, content: <AgentsTabWorkspace key="workspace" visibility="WORKSPACE" agent={agent} /> },
|
|
35
|
+
{ title: t.account, content: <AgentsTab key="account" visibility="ACCOUNT" agent={agent} /> },
|
|
35
36
|
|
|
36
37
|
], [t, isTrial, agent])
|
|
37
38
|
|
|
@@ -2,7 +2,8 @@ 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 {
|
|
5
|
+
import { agentClient, AgentResponseWithBuiltIn, workspaceAiClient } from '@stack-spot/portal-network'
|
|
6
|
+
import { VisibilityLevel } from '@stack-spot/portal-network/api/agent'
|
|
6
7
|
import { WorkspaceResponse } from '@stack-spot/portal-network/api/workspace-ai'
|
|
7
8
|
import { useCallback, useMemo, useState } from 'react'
|
|
8
9
|
import { ButtonFavorite } from '../../components/ButtonFavorite'
|
|
@@ -19,7 +20,7 @@ import { AgentLabel } from './styled'
|
|
|
19
20
|
import { useAgentFavorites } from './useAgentFavorites'
|
|
20
21
|
|
|
21
22
|
export interface AgentTabProps {
|
|
22
|
-
visibility:
|
|
23
|
+
visibility: VisibilityLevel | 'BUILT-IN',
|
|
23
24
|
workspaceId?: string,
|
|
24
25
|
agent: React.MutableRefObject<ChatProperties['agent']>,
|
|
25
26
|
showSubmitButton?: boolean,
|
|
@@ -32,15 +33,16 @@ export const AgentsTab = ({ visibility, workspaceId, agent, showSubmitButton = t
|
|
|
32
33
|
const [filter, setFilter] = useState('')
|
|
33
34
|
const { useFavorites, onAddFavorite, onRemoveFavorite } = useAgentFavorites()
|
|
34
35
|
const listFavorites = useFavorites()
|
|
35
|
-
const agentDefault =
|
|
36
|
+
const agentDefault = agentClient.agentDefault.useQuery({})
|
|
36
37
|
const agents = workspaceId
|
|
37
|
-
? workspaceAiClient.getAgentFromWorkspaceAi.useQuery({ workspaceId })
|
|
38
|
-
:
|
|
38
|
+
? workspaceAiClient.getAgentFromWorkspaceAi.useQuery({ workspaceId })
|
|
39
|
+
: agentClient.allAgents.useQuery({ visibilities: [visibility] })
|
|
40
|
+
|
|
39
41
|
|
|
40
42
|
const [value, setValue] = useState<AgentResponseWithBuiltIn | undefined>(
|
|
41
43
|
agent.current
|
|
42
44
|
? agents.find(a => a.id === agent.current?.id)
|
|
43
|
-
: chat.get('agent') ? agents.find(a => a.id === chat.get('agent')?.id) : agentDefault
|
|
45
|
+
: chat.get('agent') ? agents.find(a => a.id === chat.get('agent')?.id) : agentDefault,
|
|
44
46
|
)
|
|
45
47
|
|
|
46
48
|
const filtered = useMemo(
|
|
@@ -51,17 +53,14 @@ export const AgentsTab = ({ visibility, workspaceId, agent, showSubmitButton = t
|
|
|
51
53
|
|
|
52
54
|
function submit() {
|
|
53
55
|
if (value) {
|
|
54
|
-
chat.set(
|
|
55
|
-
'agent',
|
|
56
|
-
{ id: value.id, label: value.name, image: value.avatar!, builtIn: value.visibility_level === 'built_in', slug: value.slug },
|
|
57
|
-
)
|
|
56
|
+
chat.set('agent', { id: value.id, label: value.name, image: value.avatar, builtIn: !!value.builtIn, slug: value.slug })
|
|
58
57
|
}
|
|
59
58
|
close()
|
|
60
59
|
}
|
|
61
60
|
|
|
62
61
|
const onChange = useCallback((newValue: AgentResponseWithBuiltIn) => {
|
|
63
62
|
setValue(newValue)
|
|
64
|
-
agent.current = { ...newValue, label: newValue.name, builtIn: newValue.
|
|
63
|
+
agent.current = { ...newValue, label: newValue.name, builtIn: !!newValue.builtIn }
|
|
65
64
|
}, [])
|
|
66
65
|
|
|
67
66
|
return (
|
|
@@ -84,7 +83,13 @@ export const AgentsTab = ({ visibility, workspaceId, agent, showSubmitButton = t
|
|
|
84
83
|
<Text>{name}</Text>
|
|
85
84
|
</AgentLabel>
|
|
86
85
|
)}
|
|
87
|
-
renderDescription={a => <AgentDescription
|
|
86
|
+
renderDescription={a => <AgentDescription
|
|
87
|
+
agentId={a.id}
|
|
88
|
+
visibility={visibility}
|
|
89
|
+
description={a.description}
|
|
90
|
+
llm={a.llm_config?.model_slug}
|
|
91
|
+
numberOfKnowledgeSources={a.knowledge_sources_config?.knowledge_sources?.length ?? 0}
|
|
92
|
+
/>}
|
|
88
93
|
optionClassName={a => (a === value && filter && !a.name.toLocaleLowerCase().includes(filter.toLocaleLowerCase()))
|
|
89
94
|
? 'filtered-out'
|
|
90
95
|
: ''
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/* eslint-disable filenames/match-regex */
|
|
2
|
-
import { agentClient
|
|
2
|
+
import { agentClient } from '@stack-spot/portal-network'
|
|
3
3
|
|
|
4
4
|
export function useAgentFavorites() {
|
|
5
|
-
const useFavorites = () =>
|
|
5
|
+
const useFavorites = () => agentClient.allAgents.useQuery({ visibilities: ['FAVORITE'] })
|
|
6
6
|
const [addFavorite, pendingAddFav] = agentClient.addFavoriteAgent.useMutation()
|
|
7
7
|
const [removeFavorite, pendingRemoveFav] = agentClient.removeFavoriteAgent.useMutation()
|
|
8
8
|
|
|
9
9
|
const removeFavoriteAgent = async (idOrSlug?: string) => {
|
|
10
10
|
try {
|
|
11
11
|
await removeFavorite({ agentId: idOrSlug || '' })
|
|
12
|
-
await
|
|
12
|
+
await agentClient.allAgents.invalidate({ visibilities: ['FAVORITE'] })
|
|
13
13
|
} catch (error) {
|
|
14
14
|
// eslint-disable-next-line no-console
|
|
15
15
|
console.error(error)
|
|
@@ -19,7 +19,7 @@ export function useAgentFavorites() {
|
|
|
19
19
|
const addFavoriteAgent = async (idOrSlug?: string) => {
|
|
20
20
|
try {
|
|
21
21
|
await addFavorite({ agentId: idOrSlug || '' })
|
|
22
|
-
await
|
|
22
|
+
await agentClient.allAgents.invalidate({ visibilities: ['FAVORITE'] })
|
|
23
23
|
} catch (error) {
|
|
24
24
|
// eslint-disable-next-line no-console
|
|
25
25
|
console.error(error)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Box, Button, Checkbox, Flex, IconBox, Input, Label, Radio, Text } from '@citric/core'
|
|
2
2
|
import { Check, Cog, Copy, Dislike, DislikeFill, Like, LikeFill, TimesCircle } from '@citric/icons'
|
|
3
3
|
import { Badge, IconButton, Tooltip } from '@citric/ui'
|
|
4
|
-
import {
|
|
4
|
+
import { agentClient } from '@stack-spot/portal-network'
|
|
5
5
|
import { listToClass } from '@stack-spot/portal-theme'
|
|
6
6
|
import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
|
|
7
7
|
import { groupBy } from 'lodash'
|
|
@@ -193,11 +193,10 @@ export const ChatMessage = ({ message, isLast, beforeMessage, afterMessage }: Pr
|
|
|
193
193
|
const widget = useWidget()
|
|
194
194
|
const chat = useCurrentChat()
|
|
195
195
|
const agentId = entry.agent?.id ?? ''
|
|
196
|
-
const [
|
|
196
|
+
const [agent] = agentClient.agentById.useStatefulQuery({ agentId, builtIn: !!entry?.agent?.builtIn }, { enabled: !!agentId })
|
|
197
197
|
const [copied, setCopied] = useState(false)
|
|
198
198
|
const [showUserButtonCopy, setShowUserButtonCopy] = useState(false)
|
|
199
199
|
|
|
200
|
-
|
|
201
200
|
useChatScrollToBottomEffect(ref, [entry])
|
|
202
201
|
|
|
203
202
|
const detailKS = useCallback(({ name, slug, documentScore, documentId }: Required<TextChatEntry>['knowledgeSources'][number]) => {
|
|
@@ -349,7 +348,7 @@ export const ChatMessage = ({ message, isLast, beforeMessage, afterMessage }: Pr
|
|
|
349
348
|
className="tools-badge"
|
|
350
349
|
label={t.tools}
|
|
351
350
|
images={entry.tools.slice(0, 3).map((id) => {
|
|
352
|
-
const tool = toolById(id,
|
|
351
|
+
const tool = toolById(id, agent?.toolkits)
|
|
353
352
|
return { key: id, name: tool?.name || id, icon: <Cog />, url: tool?.image }
|
|
354
353
|
})}
|
|
355
354
|
onClick={openToolsPanel}
|
|
@@ -2,7 +2,7 @@ import { IconBox, Input } from '@citric/core'
|
|
|
2
2
|
import { Check, Download, EllipsisHorizontal, Pencil, Trash } from '@citric/icons'
|
|
3
3
|
import { IconButton, LoadingCircular } from '@citric/ui'
|
|
4
4
|
import { focusNextIgnoringChildren } from '@stack-spot/portal-components'
|
|
5
|
-
import {
|
|
5
|
+
import { aiClient } from '@stack-spot/portal-network'
|
|
6
6
|
import { ConversationResponse } from '@stack-spot/portal-network/api/ai'
|
|
7
7
|
import { theme } from '@stack-spot/portal-theme'
|
|
8
8
|
import { last } from 'lodash'
|
|
@@ -11,13 +11,12 @@ import { OverlayMenu } from '../../components/OverlayMenu'
|
|
|
11
11
|
import { useWidget } from '../../context/hooks'
|
|
12
12
|
import { ChatEntry } from '../../state/ChatEntry'
|
|
13
13
|
import { ChatState } from '../../state/ChatState'
|
|
14
|
-
import { LabeledAgent } from '../../state/types'
|
|
15
14
|
import { ButtonAction } from '../../types'
|
|
16
15
|
import { download } from '../../utils/download'
|
|
17
16
|
import { genericSourcesToKnowledgeSources } from '../../utils/knowledge-source'
|
|
18
17
|
import { useHistoryDictionary } from './dictionary'
|
|
19
18
|
import { HistoryItemBox } from './styled'
|
|
20
|
-
import { findStack, findWorkspace } from './utils'
|
|
19
|
+
import { findStack, findWorkspace, getAllAgents } from './utils'
|
|
21
20
|
|
|
22
21
|
/**
|
|
23
22
|
* Renders an item of the list of conversations (history).
|
|
@@ -89,16 +88,12 @@ export const HistoryItem = ({ item }: { item: ConversationResponse }) => {
|
|
|
89
88
|
setLoading(true)
|
|
90
89
|
try {
|
|
91
90
|
const chat = await aiClient.chat.query({ conversationId: item.id })
|
|
92
|
-
const historyAgentIds = chat.history?.map(item => item.custom_agent?.id).filter(Boolean) as string[] ?? []
|
|
93
91
|
const [stack, workspace, agents] = await Promise.all([
|
|
94
92
|
findStack(chat.ai_stack_id),
|
|
95
93
|
findWorkspace(chat.workspace_id),
|
|
96
|
-
|
|
94
|
+
getAllAgents(),
|
|
97
95
|
])
|
|
98
|
-
const
|
|
99
|
-
.map((a) => ({ ...a, label: a.name, image: a.avatar ?? '', builtIn: a.visibility_level === 'built_in' }))
|
|
100
|
-
|
|
101
|
-
const agent = agentsAsLabeledAgents.find(a => a.id === last(chat.history)?.custom_agent?.id)
|
|
96
|
+
const agent = agents.find(a => a.id === last(chat.history)?.custom_agent?.id)
|
|
102
97
|
const builtIn = !!last(chat.history ?? [])?.custom_agent?.built_in
|
|
103
98
|
widget.chatTabs.add(new ChatState({
|
|
104
99
|
id: chat.id,
|
|
@@ -108,7 +103,7 @@ export const HistoryItem = ({ item }: { item: ConversationResponse }) => {
|
|
|
108
103
|
agentType: item.agent === 'USER' ? 'user' : 'bot',
|
|
109
104
|
content: item.content,
|
|
110
105
|
type: 'md',
|
|
111
|
-
agent:
|
|
106
|
+
agent: agents.find(a => a.id === item.custom_agent?.id),
|
|
112
107
|
messageId: item.message_id,
|
|
113
108
|
knowledgeSources: item.agent === 'USER' ? undefined : genericSourcesToKnowledgeSources(item.sources),
|
|
114
109
|
updated: item.updated,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { aiClient, workspaceClient } from '@stack-spot/portal-network'
|
|
1
|
+
import { agentClient, aiClient, workspaceClient } from '@stack-spot/portal-network'
|
|
2
2
|
import { ChatProperties } from '../../state/ChatState'
|
|
3
|
+
import { LabeledWithImage } from '../../state/types'
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Finds a stack by its id.
|
|
@@ -35,3 +36,19 @@ export async function findWorkspace(id: string | null): Promise<ChatProperties['
|
|
|
35
36
|
return { id, label: id }
|
|
36
37
|
}
|
|
37
38
|
}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Finds all the agents, including common agents and public agents.
|
|
43
|
+
* @returns an array with every agent.
|
|
44
|
+
*/
|
|
45
|
+
export async function getAllAgents(): Promise<LabeledWithImage[]> {
|
|
46
|
+
try {
|
|
47
|
+
const agents = await agentClient.allAgents.query({ visibilities: ['ALL'] })
|
|
48
|
+
return agents.map(a => ({ id: a.id, label: a.name, image: a.avatar, slug: a.slug, builtIn: a.builtIn }))
|
|
49
|
+
} catch (error) {
|
|
50
|
+
// eslint-disable-next-line no-console
|
|
51
|
+
console.error(error)
|
|
52
|
+
return []
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -59,7 +59,7 @@ const dictionary = {
|
|
|
59
59
|
},
|
|
60
60
|
pt: {
|
|
61
61
|
hello: 'Olá',
|
|
62
|
-
subtitle: '
|
|
62
|
+
subtitle: 'Foque no que realmente importa. Deixe o resto com a gente.',
|
|
63
63
|
'question.meta': 'O que é a StackSpot AI?',
|
|
64
64
|
'question.ks': 'O que são Knowledge Sources?',
|
|
65
65
|
'question.agents': 'Como funcionam os agentes?',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { IconBox, Text } from '@citric/core'
|
|
2
2
|
import { Agent } from '@citric/icons'
|
|
3
|
-
import {
|
|
3
|
+
import { agentClient } from '@stack-spot/portal-network'
|
|
4
4
|
import { useMemo } from 'react'
|
|
5
5
|
import { QuickStartButton } from '../../components/QuickStartButton'
|
|
6
6
|
import { useCurrentChat, useCurrentChatState } from '../../context/hooks'
|
|
@@ -12,15 +12,15 @@ import { HomeBox } from './styled'
|
|
|
12
12
|
*/
|
|
13
13
|
export const CustomAgent = () => {
|
|
14
14
|
const { id, label, image } = useCurrentChatState('agent') ?? {}
|
|
15
|
-
const [agent] =
|
|
15
|
+
const [agent] = agentClient.agent.useStatefulQuery({ agentId: id! })
|
|
16
16
|
const chat = useCurrentChat()
|
|
17
|
-
const suggestions = useMemo(() => agent?.
|
|
17
|
+
const suggestions = useMemo(() => agent?.suggested_prompts?.map((prompt, index) => (
|
|
18
18
|
<QuickStartButton
|
|
19
19
|
key={index}
|
|
20
20
|
label={prompt}
|
|
21
21
|
onClick={() => send(prompt)}
|
|
22
22
|
/>
|
|
23
|
-
)), [agent?.
|
|
23
|
+
)), [agent?.suggested_prompts])
|
|
24
24
|
|
|
25
25
|
function send(message: string) {
|
|
26
26
|
chat.pushMessage(ChatEntry.createUserEntry(message))
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Flex, IconBox, Image } from '@citric/core'
|
|
2
2
|
import { Agent } from '@citric/icons'
|
|
3
|
-
import {
|
|
3
|
+
import { agentClient, AgentResponseWithBuiltIn } from '@stack-spot/portal-network'
|
|
4
4
|
import { useCallback } from 'react'
|
|
5
5
|
import { Selector } from '../../components/Selector'
|
|
6
6
|
import { useCurrentChat, useCurrentChatState } from '../../context/hooks'
|
|
@@ -53,9 +53,9 @@ export const AgentSelector = ({ inputRef, isTrial }: {
|
|
|
53
53
|
|
|
54
54
|
const getAgents = () => {
|
|
55
55
|
if (isTrial) {
|
|
56
|
-
return
|
|
56
|
+
return agentClient.allAgents.useQuery({ visibilities: ['PERSONAL', 'BUILT-IN'] })
|
|
57
57
|
}
|
|
58
|
-
return
|
|
58
|
+
return agentClient.allAgents.useQuery({ visibilities: ['ACCOUNT', 'SHARED', 'PERSONAL', 'BUILT-IN', 'WORKSPACE'] })
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
return <Selector
|
|
@@ -68,7 +68,7 @@ export const AgentSelector = ({ inputRef, isTrial }: {
|
|
|
68
68
|
regex: agentRegex,
|
|
69
69
|
urlBuilder: (agent) => `/agents/${agent?.id}`,
|
|
70
70
|
searchProp: 'name',
|
|
71
|
-
sections: isTrial ? ['favorite', 'personal', '
|
|
71
|
+
sections: isTrial ? ['favorite', 'personal', 'built-in'] : ['favorite', 'personal', 'workspace', 'account', 'shared', 'built-in'],
|
|
72
72
|
renderComponentItem: AgentItem,
|
|
73
73
|
isEnabled: isAgentEnabled,
|
|
74
74
|
onSelect: onSelectItem,
|
|
@@ -2,14 +2,14 @@ import { Flex, IconBox } from '@citric/core'
|
|
|
2
2
|
import { Agent, TimesMini } from '@citric/icons'
|
|
3
3
|
import { IconButton, Tooltip } from '@citric/ui'
|
|
4
4
|
import { MiniLogo } from '@stack-spot/portal-components/svg'
|
|
5
|
-
import {
|
|
5
|
+
import { agentClient } from '@stack-spot/portal-network'
|
|
6
6
|
import { useEffect } from 'react'
|
|
7
7
|
import { useCurrentChat, useCurrentChatState, useWidget } from '../../context/hooks'
|
|
8
8
|
import { useMessageInputDictionary } from './dictionary'
|
|
9
9
|
|
|
10
10
|
export const ButtonAgent = () => {
|
|
11
11
|
const t = useMessageInputDictionary()
|
|
12
|
-
const agentDefault =
|
|
12
|
+
const agentDefault = agentClient.agentDefault.useQuery({})
|
|
13
13
|
const widget = useWidget()
|
|
14
14
|
const chat = useCurrentChat()
|
|
15
15
|
const agent = useCurrentChatState('agent')
|