@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.
Files changed (83) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/app-metadata.json +3 -3
  3. package/dist/chat-interceptors/quick-commands.d.ts.map +1 -1
  4. package/dist/chat-interceptors/quick-commands.js +12 -0
  5. package/dist/chat-interceptors/quick-commands.js.map +1 -1
  6. package/dist/components/AgentCard/dictionary.d.ts +2 -4
  7. package/dist/components/AgentCard/dictionary.d.ts.map +1 -1
  8. package/dist/components/AgentCard/dictionary.js +2 -4
  9. package/dist/components/AgentCard/dictionary.js.map +1 -1
  10. package/dist/components/Selector/index.d.ts +2 -2
  11. package/dist/components/Selector/index.d.ts.map +1 -1
  12. package/dist/components/Selector/index.js +2 -2
  13. package/dist/components/Selector/index.js.map +1 -1
  14. package/dist/state/constants.js +2 -2
  15. package/dist/state/constants.js.map +1 -1
  16. package/dist/state/types.d.ts +1 -1
  17. package/dist/state/types.d.ts.map +1 -1
  18. package/dist/utils/tools.d.ts +2 -2
  19. package/dist/utils/tools.d.ts.map +1 -1
  20. package/dist/utils/tools.js +6 -3
  21. package/dist/utils/tools.js.map +1 -1
  22. package/dist/views/Agents/AgentDescription.d.ts +9 -2
  23. package/dist/views/Agents/AgentDescription.d.ts.map +1 -1
  24. package/dist/views/Agents/AgentDescription.js +9 -11
  25. package/dist/views/Agents/AgentDescription.js.map +1 -1
  26. package/dist/views/Agents/AgentsPanel.d.ts.map +1 -1
  27. package/dist/views/Agents/AgentsPanel.js +11 -11
  28. package/dist/views/Agents/AgentsPanel.js.map +1 -1
  29. package/dist/views/Agents/AgentsTab.d.ts +2 -2
  30. package/dist/views/Agents/AgentsTab.d.ts.map +1 -1
  31. package/dist/views/Agents/AgentsTab.js +6 -6
  32. package/dist/views/Agents/AgentsTab.js.map +1 -1
  33. package/dist/views/Agents/useAgentFavorites.d.ts +1 -1
  34. package/dist/views/Agents/useAgentFavorites.js +4 -4
  35. package/dist/views/Agents/useAgentFavorites.js.map +1 -1
  36. package/dist/views/Chat/ChatMessage.d.ts.map +1 -1
  37. package/dist/views/Chat/ChatMessage.js +3 -3
  38. package/dist/views/Chat/ChatMessage.js.map +1 -1
  39. package/dist/views/ChatHistory/HistoryItem.d.ts.map +1 -1
  40. package/dist/views/ChatHistory/HistoryItem.js +5 -8
  41. package/dist/views/ChatHistory/HistoryItem.js.map +1 -1
  42. package/dist/views/ChatHistory/utils.d.ts +6 -0
  43. package/dist/views/ChatHistory/utils.d.ts.map +1 -1
  44. package/dist/views/ChatHistory/utils.js +16 -1
  45. package/dist/views/ChatHistory/utils.js.map +1 -1
  46. package/dist/views/Home/BuiltInAgent.js +1 -1
  47. package/dist/views/Home/BuiltInAgent.js.map +1 -1
  48. package/dist/views/Home/CustomAgent.js +3 -3
  49. package/dist/views/Home/CustomAgent.js.map +1 -1
  50. package/dist/views/MessageInput/AgentSelector.js +4 -4
  51. package/dist/views/MessageInput/AgentSelector.js.map +1 -1
  52. package/dist/views/MessageInput/ButtonAgent.js +2 -2
  53. package/dist/views/MessageInput/ButtonAgent.js.map +1 -1
  54. package/dist/views/MessageInput/QuickCommandSelector.js +4 -4
  55. package/dist/views/MessageInput/QuickCommandSelector.js.map +1 -1
  56. package/dist/views/MessageInput/dictionary.js +1 -1
  57. package/dist/views/MessageInput/dictionary.js.map +1 -1
  58. package/dist/views/Tools.js +3 -3
  59. package/dist/views/Tools.js.map +1 -1
  60. package/dist/views/Workspaces/WorkspacesTab.js +1 -1
  61. package/package.json +8 -8
  62. package/src/app-metadata.json +3 -3
  63. package/src/chat-interceptors/quick-commands.ts +15 -2
  64. package/src/components/AgentCard/dictionary.ts +2 -4
  65. package/src/components/Selector/index.tsx +5 -4
  66. package/src/state/constants.ts +2 -2
  67. package/src/state/types.ts +1 -1
  68. package/src/utils/tools.ts +7 -5
  69. package/src/views/Agents/AgentDescription.tsx +25 -18
  70. package/src/views/Agents/AgentsPanel.tsx +12 -11
  71. package/src/views/Agents/AgentsTab.tsx +17 -12
  72. package/src/views/Agents/useAgentFavorites.ts +4 -4
  73. package/src/views/Chat/ChatMessage.tsx +3 -4
  74. package/src/views/ChatHistory/HistoryItem.tsx +5 -10
  75. package/src/views/ChatHistory/utils.ts +18 -1
  76. package/src/views/Home/BuiltInAgent.tsx +1 -1
  77. package/src/views/Home/CustomAgent.tsx +4 -4
  78. package/src/views/MessageInput/AgentSelector.tsx +4 -4
  79. package/src/views/MessageInput/ButtonAgent.tsx +2 -2
  80. package/src/views/MessageInput/QuickCommandSelector.tsx +4 -4
  81. package/src/views/MessageInput/dictionary.ts +1 -1
  82. package/src/views/Tools.tsx +3 -4
  83. 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.0",
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": "139.1-beta.0",
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
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stack-spot/ai-chat-widget",
3
- "version": "1.27.0-beta.0",
4
- "date": "Wed Jun 11 2025 16:46:22 GMT-0300 (Horário Padrão de Brasília)",
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.139.1-beta.0(@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)"
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
- 'built_in': 'Embutido',
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
- 'built_in': 'Embutido',
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 { AgentVisibilityLevel } from '@stack-spot/portal-network'
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 = AgentVisibilityLevel
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
- 'built_in': 'Built-in',
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
- 'built_in': 'Embutido',
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.',
@@ -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', 'cbl', 'cpp', 'cxx', 'cc', 'c', 'hpp', 'hxx', 'hh', 'h', 'cs',
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
  ]
@@ -4,7 +4,7 @@ export interface Labeled {
4
4
  }
5
5
 
6
6
  export interface LabeledWithImage extends Labeled {
7
- image?: string | undefined | null,
7
+ image?: string,
8
8
  }
9
9
 
10
10
  export interface LabeledAgent extends LabeledWithImage {
@@ -1,9 +1,11 @@
1
- import { BuiltinToolkitResponse, BuiltinToolResponse } from '@stack-spot/portal-network/api/agent'
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: BuiltinToolkitResponse[] | undefined): ToolWithImage | undefined {
7
- const tools = toolkits?.map(({ image_url, tools }) => tools?.map((tool) => ({ ...tool, id: tool.id!, image: image_url! }))).flat()
8
- return keyBy(tools, 'id')[id]
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 { agentToolsClient } from '@stack-spot/portal-network'
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
- export const AgentDescription = ({ agentId }: { agentId?: string }) => {
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 }] = agentToolsClient.agent.useStatefulQuery({ agentId: agentId! }, { enabled: !!agentId })
13
- const [toolKits, , , { isLoading: isLoadingToolKit }] = agentToolsClient.tools.useStatefulQuery()
14
- const numberOfKnowledgeSources = agent?.knowledge_source_config?.knowledge_sources.length ?? 0
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?.knowledge_source_config?.knowledge_sources?.map((ks, index) => (
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 tool of agent?.tools ?? []) {
32
- const toolWithImage = toolById(tool.builtin_tool_id, toolKits)
33
- result.push(<li key={tool.builtin_tool_id}>
34
- <ToolBadge name={toolWithImage?.name || toolWithImage?.id || 'unknown'} image={toolWithImage?.image} />
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
- {agent?.description && <section>
49
+ {description && <section>
43
50
  <Text appearance="microtext1" className="title">{t.description}</Text>
44
- <Text>{agent?.description}</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 || isLoadingToolKit ? skeleton : knowledgeSources}</ul>
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
- {agent?.model_name && <section>
61
+ {llm && <section>
55
62
  <Text appearance="microtext1" className="title">LLM</Text>
56
- <Badge palette="orange" appearance="square">{agent?.model_name}</Badge>
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 (agentToolsClient.agentDefaultSlug !== chat.get('agent')?.slug) {
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="favorite" agent={agent} /> },
26
- { title: t.builtin, content: <AgentsTab key="builtin" visibility="built_in" agent={agent} /> },
27
- { title: t.personal, content: <AgentsTab key="personal" visibility="personal" agent={agent} /> },
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="favorite" agent={agent} /> },
30
- { title: t.builtin, content: <AgentsTab key="builtin" visibility="built_in" agent={agent} /> },
31
- { title: t.personal, content: <AgentsTab key="personal" visibility="personal" agent={agent} /> },
32
- { title: t.shared, content: <AgentsTab key="shared" visibility="shared" agent={agent} /> },
33
- { title: t.spots, content: <AgentsTabWorkspace key="workspace" visibility="workspace" agent={agent} /> },
34
- { title: t.account, content: <AgentsTab key="account" visibility="account" agent={agent} /> },
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 { AgentResponseWithBuiltIn, agentToolsClient, AgentVisibilityLevel, workspaceAiClient } from '@stack-spot/portal-network'
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: AgentVisibilityLevel,
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 = agentToolsClient.agentDefault.useQuery()
36
+ const agentDefault = agentClient.agentDefault.useQuery({})
36
37
  const agents = workspaceId
37
- ? workspaceAiClient.getAgentFromWorkspaceAi.useQuery({ workspaceId }) as AgentResponseWithBuiltIn[]
38
- : agentToolsClient.agents.useQuery({ visibility })
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 as AgentResponseWithBuiltIn,
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.visibility_level === 'built_in' }
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 agentId={a.id} />}
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, agentToolsClient } from '@stack-spot/portal-network'
2
+ import { agentClient } from '@stack-spot/portal-network'
3
3
 
4
4
  export function useAgentFavorites() {
5
- const useFavorites = () => agentToolsClient.agents.useQuery({ visibility: 'favorite' })
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 agentToolsClient.agents.invalidate({ visibility: 'favorite' })
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 agentToolsClient.agents.invalidate({ visibility: 'favorite' })
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 { agentToolsClient } from '@stack-spot/portal-network'
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 [toolKits] = agentToolsClient.tools.useStatefulQuery({ enabled: !!agentId })
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, toolKits)
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 { agentToolsClient, aiClient } from '@stack-spot/portal-network'
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
- agentToolsClient.agentsByIds.query({ searchAgentsRequest: { ids: historyAgentIds } }),
94
+ getAllAgents(),
97
95
  ])
98
- const agentsAsLabeledAgents: LabeledAgent[] = agents
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: agentsAsLabeledAgents.find(a => a.id === item.custom_agent?.id),
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: 'O que realmente importa leva tempo, deixe que a gente cuide do resto.',
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 { agentToolsClient } from '@stack-spot/portal-network'
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] = agentToolsClient.agent.useStatefulQuery({ agentId: id! })
15
+ const [agent] = agentClient.agent.useStatefulQuery({ agentId: id! })
16
16
  const chat = useCurrentChat()
17
- const suggestions = useMemo(() => agent?.conversation_starter?.map((prompt, index) => (
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?.conversation_starter])
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 { AgentResponseWithBuiltIn, agentToolsClient } from '@stack-spot/portal-network'
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 agentToolsClient.allAgents.useQuery({ visibilities: ['personal', 'built_in'] })
56
+ return agentClient.allAgents.useQuery({ visibilities: ['PERSONAL', 'BUILT-IN'] })
57
57
  }
58
- return agentToolsClient.allAgents.useQuery({ visibilities: ['account', 'shared', 'personal', 'built_in', 'workspace'] })
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', 'built_in'] : ['favorite', 'personal', 'workspace', 'account', 'shared', 'built_in'],
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 { agentToolsClient } from '@stack-spot/portal-network'
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 = agentToolsClient.agentDefault.useQuery()
12
+ const agentDefault = agentClient.agentDefault.useQuery({})
13
13
  const widget = useWidget()
14
14
  const chat = useCurrentChat()
15
15
  const agent = useCurrentChatState('agent')