@stack-spot/ai-chat-widget 1.0.0-dev.1769003016623 → 1.0.0-dev.1769537635610

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 (89) hide show
  1. package/CHANGELOG.md +7 -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 +9 -232
  5. package/dist/chat-interceptors/quick-commands.js.map +1 -1
  6. package/dist/chat-interceptors/send-message.d.ts.map +1 -1
  7. package/dist/chat-interceptors/send-message.js +5 -1
  8. package/dist/chat-interceptors/send-message.js.map +1 -1
  9. package/dist/components/Selector/SelectVersion.d.ts +12 -0
  10. package/dist/components/Selector/SelectVersion.d.ts.map +1 -0
  11. package/dist/components/Selector/SelectVersion.js +33 -0
  12. package/dist/components/Selector/SelectVersion.js.map +1 -0
  13. package/dist/components/Selector/index.d.ts +2 -0
  14. package/dist/components/Selector/index.d.ts.map +1 -1
  15. package/dist/components/Selector/index.js +5 -2
  16. package/dist/components/Selector/index.js.map +1 -1
  17. package/dist/components/Selector/styled.d.ts +2 -0
  18. package/dist/components/Selector/styled.d.ts.map +1 -1
  19. package/dist/components/Selector/styled.js +45 -0
  20. package/dist/components/Selector/styled.js.map +1 -1
  21. package/dist/hooks/enabled-feature-flags.d.ts +5 -0
  22. package/dist/hooks/enabled-feature-flags.d.ts.map +1 -0
  23. package/dist/hooks/enabled-feature-flags.js +28 -0
  24. package/dist/hooks/enabled-feature-flags.js.map +1 -0
  25. package/dist/state/types.d.ts +1 -0
  26. package/dist/state/types.d.ts.map +1 -1
  27. package/dist/utils/tools.d.ts +5 -5
  28. package/dist/utils/tools.d.ts.map +1 -1
  29. package/dist/utils/tools.js +2 -2
  30. package/dist/utils/tools.js.map +1 -1
  31. package/dist/views/Agents/AgentDescription.d.ts +6 -2
  32. package/dist/views/Agents/AgentDescription.d.ts.map +1 -1
  33. package/dist/views/Agents/AgentDescription.js +25 -10
  34. package/dist/views/Agents/AgentDescription.js.map +1 -1
  35. package/dist/views/Agents/AgentsTab.d.ts.map +1 -1
  36. package/dist/views/Agents/AgentsTab.js +21 -4
  37. package/dist/views/Agents/AgentsTab.js.map +1 -1
  38. package/dist/views/Agents/dictionary.d.ts +1 -1
  39. package/dist/views/Agents/dictionary.d.ts.map +1 -1
  40. package/dist/views/Agents/dictionary.js +2 -0
  41. package/dist/views/Agents/dictionary.js.map +1 -1
  42. package/dist/views/Chat/ChatMessage.d.ts.map +1 -1
  43. package/dist/views/Chat/ChatMessage.js +6 -5
  44. package/dist/views/Chat/ChatMessage.js.map +1 -1
  45. package/dist/views/ChatHistory/utils.d.ts.map +1 -1
  46. package/dist/views/ChatHistory/utils.js +14 -7
  47. package/dist/views/ChatHistory/utils.js.map +1 -1
  48. package/dist/views/Editor.d.ts.map +1 -1
  49. package/dist/views/Editor.js +16 -2
  50. package/dist/views/Editor.js.map +1 -1
  51. package/dist/views/Home/CustomAgent.js +3 -3
  52. package/dist/views/Home/CustomAgent.js.map +1 -1
  53. package/dist/views/MessageInput/AgentSelector.d.ts.map +1 -1
  54. package/dist/views/MessageInput/AgentSelector.js +11 -1
  55. package/dist/views/MessageInput/AgentSelector.js.map +1 -1
  56. package/dist/views/MessageInput/ModelSwitcher/index.d.ts.map +1 -1
  57. package/dist/views/MessageInput/ModelSwitcher/index.js +3 -1
  58. package/dist/views/MessageInput/ModelSwitcher/index.js.map +1 -1
  59. package/dist/views/MessageInput/ModelSwitcher/utils.d.ts +2 -2
  60. package/dist/views/MessageInput/ModelSwitcher/utils.d.ts.map +1 -1
  61. package/dist/views/MessageInput/ModelSwitcher/utils.js +6 -6
  62. package/dist/views/MessageInput/ModelSwitcher/utils.js.map +1 -1
  63. package/dist/views/Resources.js +8 -5
  64. package/dist/views/Resources.js.map +1 -1
  65. package/dist/views/Steps/dictionary.d.ts +1 -1
  66. package/dist/views/Tools.js +3 -2
  67. package/dist/views/Tools.js.map +1 -1
  68. package/package.json +2 -2
  69. package/src/app-metadata.json +3 -3
  70. package/src/chat-interceptors/quick-commands.ts +14 -275
  71. package/src/chat-interceptors/send-message.ts +6 -2
  72. package/src/components/Selector/SelectVersion.tsx +55 -0
  73. package/src/components/Selector/index.tsx +11 -2
  74. package/src/components/Selector/styled.ts +47 -0
  75. package/src/hooks/enabled-feature-flags.ts +31 -0
  76. package/src/state/types.ts +1 -0
  77. package/src/utils/tools.ts +4 -4
  78. package/src/views/Agents/AgentDescription.tsx +48 -14
  79. package/src/views/Agents/AgentsTab.tsx +31 -13
  80. package/src/views/Agents/dictionary.ts +2 -1
  81. package/src/views/Chat/ChatMessage.tsx +8 -6
  82. package/src/views/ChatHistory/utils.ts +18 -10
  83. package/src/views/Editor.tsx +20 -3
  84. package/src/views/Home/CustomAgent.tsx +4 -4
  85. package/src/views/MessageInput/AgentSelector.tsx +15 -5
  86. package/src/views/MessageInput/ModelSwitcher/index.tsx +3 -2
  87. package/src/views/MessageInput/ModelSwitcher/utils.tsx +9 -8
  88. package/src/views/Resources.tsx +10 -6
  89. package/src/views/Tools.tsx +5 -4
@@ -1,17 +1,31 @@
1
1
  import { Icon } from '@stack-spot/citric-icons'
2
- import { AsyncContent, Badge, Card, IconBox, ImageBox, ImageWithFallback, Text } from '@stack-spot/citric-react'
2
+ import { AsyncContent, Badge, Card, IconBox, ImageBox, ImageWithFallback, Row, Text } from '@stack-spot/citric-react'
3
3
  import { agentToolsClient } from '@stack-spot/portal-network'
4
- import { useMemo } from 'react'
4
+ import { useEffect, useMemo, useState } from 'react'
5
+ import { SelectVersion } from '../../components/Selector/SelectVersion'
6
+ import { VersionSelectorBox } from '../../components/Selector/styled'
5
7
  import { useAgentsDictionary } from './dictionary'
6
8
  import { AgentDescriptionBox } from './styled'
7
9
 
8
- export const AgentDescription = ({ agentId }: { agentId?: string }) => {
10
+ interface Props {
11
+ agentId?: string,
12
+ enableVersionSelect?: boolean,
13
+ onVersionChange?: (version?: number) => void,
14
+ }
15
+
16
+ export const AgentDescription = ({ agentId, enableVersionSelect, onVersionChange }:Props) => {
9
17
  const t = useAgentsDictionary()
10
- const [agent,, error, { isLoading }] = agentToolsClient.agent.useStatefulQuery({ agentId: agentId! }, { enabled: !!agentId })
11
- const numberOfKnowledgeSources = agent?.knowledge_sources_config?.knowledge_sources.length ?? 0
18
+ const [selectedVersion, setSelectedVersion] = useState<number | undefined>(undefined)
19
+ const [agent,, error, { isLoading }] = agentToolsClient.agentV2.useStatefulQuery({ agentCoreId: agentId!,
20
+ versionNumber: selectedVersion }, { enabled: !!agentId })
21
+ const [listVersions, , errorAgentWithVersion, { isLoading: isLoadingAgentWithVersions }] =
22
+ agentToolsClient.listAgentVersions.useStatefulQuery({ agentCoreId: agentId! },
23
+ { enabled: enableVersionSelect && !!agentId })
24
+ const optionsVersions = listVersions?.map((version) => version.version_number)
25
+ const numberOfKnowledgeSources = agent?.version.knowledge_sources_config?.knowledge_sources.length ?? 0
12
26
 
13
27
  const knowledgeSources = useMemo(
14
- () => agent?.knowledge_sources_config?.knowledge_sources_details?.map((ks, index) => (
28
+ () => agent?.version.knowledge_sources_config?.knowledge_sources_details?.map((ks, index) => (
15
29
  <li key={index}>
16
30
  <Card gap="10px" direction="row" flex={1} size="xxs" bgLevel={500} justifyContent="space-between">
17
31
  <Text color="light.contrastText">{ks.name}</Text>
@@ -21,12 +35,12 @@ export const AgentDescription = ({ agentId }: { agentId?: string }) => {
21
35
  )),
22
36
  [agent],
23
37
  )
24
-
38
+
25
39
  const { tools, multiAgents } = useMemo(() => {
26
40
  const tools: React.ReactElement[] = []
27
41
  const multiAgents: React.ReactElement[] = []
28
- const builtInTools = agent?.toolkits?.builtin_toolkits ?? []
29
- const customToolkits = agent?.toolkits?.custom_toolkits ?? []
42
+ const builtInTools = agent?.version.toolkits?.builtin_toolkits ?? []
43
+ const customToolkits = agent?.version.toolkits?.custom_toolkits ?? []
30
44
  for (const toolkit of builtInTools) {
31
45
  for (const tool of toolkit.tools ?? []) {
32
46
  if (toolkit.id == 'UTILITIES'){
@@ -66,22 +80,42 @@ export const AgentDescription = ({ agentId }: { agentId?: string }) => {
66
80
  return { tools, multiAgents }
67
81
  }, [agent])
68
82
 
69
- const mcpToolkits = useMemo(() => agent?.toolkits?.mcp_toolkits?.map(t => (
83
+ const mcpToolkits = useMemo(() => agent?.version.toolkits?.mcp_toolkits?.map(t => (
70
84
  <li key={`mcp-${t.id}`}>
71
85
  <Card gap="10px" direction="row" flex={1} size="xxs" bgLevel={500}>
72
86
  <ImageBox><ImageWithFallback src={t.avatar ?? undefined} fallback={<Icon icon="Cog" />} /></ImageBox>
73
87
  <Text color="light.contrastText">{t.name}</Text>
74
88
  </Card>
75
89
  </li>
76
- )), [agent?.toolkits?.mcp_toolkits])
90
+ )), [agent?.version.toolkits?.mcp_toolkits])
91
+
92
+ useEffect(() => {
93
+ if (!selectedVersion && agent?.version.version_number !== selectedVersion){
94
+ setSelectedVersion(agent?.version.version_number)
95
+ }
96
+ }, [agent?.version.version_number])
97
+
98
+ const onChangeVersion = (version?: number) => {
99
+ setSelectedVersion(version)
100
+ onVersionChange?.(version)
101
+ }
77
102
 
78
103
  return (
79
- <AsyncContent loading={isLoading} error={error}>
104
+ <AsyncContent loading={isLoading || isLoadingAgentWithVersions} error={error || errorAgentWithVersion}>
80
105
  <AgentDescriptionBox>
81
106
  {agent?.description && <section>
82
107
  <Text appearance="microtext1" className="title">{t.description}</Text>
83
108
  <Text>{agent?.description}</Text>
84
109
  </section>}
110
+ {enableVersionSelect && optionsVersions && optionsVersions?.length > 0 && <section>
111
+ <VersionSelectorBox>
112
+ <Row justifyContent="space-between" p={4}>
113
+ <Text>{t.version}</Text>
114
+ <SelectVersion options={optionsVersions} value={selectedVersion}
115
+ onChange={(value?: any) => onChangeVersion(value)} id={agent?.id ?? ''} />
116
+ </Row>
117
+ </VersionSelectorBox>
118
+ </section>}
85
119
  {(!!numberOfKnowledgeSources || !!knowledgeSources?.length) && <section>
86
120
  <Text appearance="microtext1" className="title">Knowledge sources</Text>
87
121
  <ul>{knowledgeSources}</ul>
@@ -97,9 +131,9 @@ export const AgentDescription = ({ agentId }: { agentId?: string }) => {
97
131
  <Text appearance="microtext1" className="title">{t.multiAgent}</Text>
98
132
  <ul>{multiAgents}</ul>
99
133
  </section>}
100
- {agent?.model_name && <section>
134
+ {agent?.version.model_name && <section>
101
135
  <Text appearance="microtext1" className="title">LLM</Text>
102
- <Badge colorPalette="orange" appearance="square">{agent?.model_name}</Badge>
136
+ <Badge colorPalette="orange" appearance="square">{agent?.version.model_name}</Badge>
103
137
  </section>}
104
138
  </AgentDescriptionBox>
105
139
  </AsyncContent>
@@ -9,6 +9,7 @@ import { NavigationComponent } from '../../components/ComponentNavigator'
9
9
  import { DescribedRadioGroup } from '../../components/form/DescribedRadioGroup'
10
10
  import { WorkspaceTabNavigator } from '../../components/WorkspaceTabNavigator'
11
11
  import { useCurrentChat } from '../../context/hooks'
12
+ import { useIsFeatureFlagEnabled } from '../../hooks/enabled-feature-flags'
12
13
  import { useRightPanel } from '../../right-panel/hooks'
13
14
  import { ChatProperties } from '../../state/ChatState'
14
15
  import { AgentDescription } from './AgentDescription'
@@ -28,9 +29,10 @@ export const AgentsTab = ({ visibility, workspaceId, agent, showSubmitButton = t
28
29
  const chat = useCurrentChat()
29
30
  const { useFavorites, onAddFavorite, onRemoveFavorite } = useAgentFavorites()
30
31
  const [submitEnabled, setSubmitEnabled] = useState(false)
32
+ const featureFlag = useIsFeatureFlagEnabled('ENABLE_VERSION_CONTENT_AI')
31
33
  const listFavorites = useFavorites()
32
34
  const agentDefault = agentToolsClient.agentDefault.useQuery()
33
-
35
+ const [agentVersions, setAgentVersions] = useState<Record<string, number | undefined>>({})
34
36
  const [filter, setFilter] = useState<string | undefined>()
35
37
  const [apiFilter, setApiFilter] = useState<string | undefined>()
36
38
  const [isPending, startTransition] = useTransition()
@@ -59,15 +61,15 @@ export const AgentsTab = ({ visibility, workspaceId, agent, showSubmitButton = t
59
61
 
60
62
  const agents = workspaceId ? workspaceAgents : agentsData
61
63
 
62
- const initialValue = useMemo<AgentResponseWithBuiltIn | undefined>(
63
- () => {
64
- const initial = agent.current
65
- ? agents?.find(a => a.id === agent.current?.id)
66
- : chat.get('agent') ? agents?.find(a => a.id === chat.get('agent')?.id) : agentDefault as unknown as AgentResponseWithBuiltIn
67
- if (initial && !submitEnabled) setSubmitEnabled(true)
68
- return initial
69
- },
70
- [agents],
64
+ const initialValue = useMemo<AgentResponseWithBuiltIn | undefined>(() => {
65
+ const initial = agent.current
66
+ ? agents?.find(a => a.id === agent.current?.id)
67
+ : chat.get('agent') ?
68
+ agents?.find(a => a.id === chat.get('agent')?.id) : { ...agentDefault, suggested_prompts: null } as AgentResponseWithBuiltIn
69
+ if (initial && !submitEnabled) setSubmitEnabled(true)
70
+ return initial
71
+ },
72
+ [agents],
71
73
  )
72
74
 
73
75
  function submit() {
@@ -75,12 +77,26 @@ export const AgentsTab = ({ visibility, workspaceId, agent, showSubmitButton = t
75
77
  close()
76
78
  }
77
79
 
80
+ const onVersionChange = (ag: AgentResponseWithBuiltIn, version?: number) => {
81
+ setAgentVersions(prev => ({
82
+ ...prev,
83
+ [ag.id]: version,
84
+ }))
85
+
86
+ if (agent.current?.id === ag.id) {
87
+ agent.current = {
88
+ ...agent.current,
89
+ agent_version_number: version,
90
+ }
91
+ }
92
+ }
93
+
78
94
  return <>
79
95
  <div className="content">
80
96
  <DescribedRadioGroup
81
97
  fetchNextPage={fetchNextPage}
82
98
  hasNextPage={hasNextPage && !workspaceId}
83
- options={agents}
99
+ options={agents || []}
84
100
  initialValue={initialValue}
85
101
  filter={workspaceId ? undefined : filter}
86
102
  setFilter={workspaceId ? undefined : (value?: string) => {
@@ -89,7 +105,8 @@ export const AgentsTab = ({ visibility, workspaceId, agent, showSubmitButton = t
89
105
  }}
90
106
  onChange={(ag) => {
91
107
  agent.current = ag
92
- ? { ...ag, label: ag.name, image: ag.avatar!, slug: ag.slug, builtIn: ag.visibility_level === 'built_in' }
108
+ ? { ...ag, label: ag.name, image: ag.avatar!, slug: ag.slug, builtIn: ag.visibility_level === 'built_in',
109
+ agent_version_number: agentVersions[ag.id] ?? ag.version_number }
93
110
  : undefined
94
111
  setSubmitEnabled(true)
95
112
  }}
@@ -98,7 +115,8 @@ export const AgentsTab = ({ visibility, workspaceId, agent, showSubmitButton = t
98
115
  idOrSlug: ag.id,
99
116
  // below, "key" is important. I don't know why exactly, but sometimes the avatar doesn't update if we don't do this.
100
117
  image: <ImageWithFallback key={ag.id} src={ag.avatar ?? undefined} fallback={<Icon icon="Agent" />} />,
101
- description: <AgentDescription agentId={ag.id} />,
118
+ description: <AgentDescription agentId={ag.id} enableVersionSelect={featureFlag.flagEnabled}
119
+ onVersionChange={(version?: number) => onVersionChange(ag, version)} />,
102
120
  name: ag.name,
103
121
  listFavorites,
104
122
  onAddFavorite,
@@ -19,6 +19,7 @@ const dictionary = {
19
19
  tools: 'Tools',
20
20
  spots: 'Spots',
21
21
  multiAgent: 'Multi-agents',
22
+ version: 'Version',
22
23
  },
23
24
  pt: {
24
25
  title: 'Agentes',
@@ -38,7 +39,7 @@ const dictionary = {
38
39
  tools: 'Ferramentas',
39
40
  spots: 'Spots',
40
41
  multiAgent: 'Multi-agents',
41
-
42
+ version: 'Versão',
42
43
  },
43
44
  } satisfies Dictionary
44
45
 
@@ -215,14 +215,16 @@ export const ChatMessage = ({ message, isLast, beforeMessage, afterMessage, cust
215
215
  const chat = useCurrentChat()
216
216
  const agentId = entry.agent?.id ?? ''
217
217
  // enabled: we don't want to make any request if there is no agent
218
- const [agent] = agentToolsClient.agent.useStatefulQuery({ agentId }, { enabled: !!agentId })
218
+ const [agent] = agentToolsClient.agentV2.useStatefulQuery({ agentCoreId: agentId, versionNumber: entry.agent?.agent_version_number },
219
+ { enabled: !!agentId })
219
220
  const toolkits = useMemo(() => [
220
- ...agent?.toolkits?.builtin_toolkits ?? [],
221
- ...agent?.toolkits?.custom_toolkits ?? [],
222
- ...agent?.toolkits?.mcp_toolkits ?? [],
221
+ ...agent?.version?.toolkits?.builtin_toolkits ?? [],
222
+ ...agent?.version?.toolkits?.custom_toolkits ?? [],
223
+ ...agent?.version?.toolkits?.mcp_toolkits ?? [],
223
224
  ], [agent])
224
- const [agentsTools] = agentToolsClient.agentsByIds.useStatefulQuery(
225
- { searchAgentsRequest: { ids: entry.tools || [''] } }, { enabled: !!entry.tools?.length })
225
+ const agentsSearch = entry.tools?.map((id) => ({ agent_core_id: id })) ?? []
226
+ const [agentsTools] = agentToolsClient.agentsByIdsV2.useStatefulQuery(
227
+ { searchAgentsRequestV2: { agents: agentsSearch } }, { enabled: !!entry.tools?.length })
226
228
  const [copied, setCopied] = useState(false)
227
229
  const [showUserButtonCopy, setShowUserButtonCopy] = useState(false)
228
230
  const isPlanning = useCurrentChatState('isPlaning') ?? false
@@ -1,5 +1,5 @@
1
1
  import { agentToolsClient, aiClient, AnswerChatStep, ChatAgentTool, ChatStep, PlanningChatStep, workspaceClient } from '@stack-spot/portal-network'
2
- import { AgentModel } from '@stack-spot/portal-network/api/agent-tools'
2
+ import { AgentCoreWithSingleVersionResponse2 } from '@stack-spot/portal-network/api/agent-tools'
3
3
  import { last } from 'lodash'
4
4
  import { ChatEntry } from '../../state/ChatEntry'
5
5
  import { ChatProperties, ChatState } from '../../state/ChatState'
@@ -56,11 +56,11 @@ function toJSONString(data: any) {
56
56
  return `${data}`
57
57
  }
58
58
 
59
- function findTool(agent: AgentModel | undefined, id: string) {
59
+ function findTool(agent: AgentCoreWithSingleVersionResponse2 | undefined, id: string) {
60
60
  const allToolkits = [
61
- ...agent?.toolkits?.builtin_toolkits ?? [],
62
- ...agent?.toolkits?.custom_toolkits ?? [],
63
- ...agent?.toolkits?.mcp_toolkits ?? [],
61
+ ...agent?.version?.toolkits?.builtin_toolkits ?? [],
62
+ ...agent?.version?.toolkits?.custom_toolkits ?? [],
63
+ ...agent?.version?.toolkits?.mcp_toolkits ?? [],
64
64
  ]
65
65
  for (const toolkit of allToolkits) {
66
66
  for (const tool of toolkit.tools ?? []) {
@@ -75,9 +75,10 @@ async function stepsFromAgentInfo(
75
75
  ): Promise<ChatStep[] | undefined> {
76
76
  const planningInfo = agentInfo?.find(i => i.type === 'planning' && !!i.data)
77
77
  if (planningInfo) {
78
- let agent: AgentModel | undefined
78
+ let agent: AgentCoreWithSingleVersionResponse2 | undefined
79
79
  try {
80
- agent = agentId ? await agentToolsClient.agent.query({ agentId }) : undefined
80
+ //TODO: avaliar se vamos precisar da versao aqui
81
+ agent = agentId ? await agentToolsClient.agentV2.query({ agentCoreId: agentId }) : undefined
81
82
  } catch { /* empty */ }
82
83
  const planning: PlanningChatStep = {
83
84
  type: 'planning',
@@ -105,7 +106,7 @@ async function stepsFromAgentInfo(
105
106
  return {
106
107
  id: t.tool_id,
107
108
  executionId: t.tool_execution_id,
108
- name: tool?.name,
109
+ name: ('name' in tool ? tool.name : ('function' in tool ? tool?.function?.name : undefined) ?? ''),
109
110
  description: 'description' in tool ? tool.description : undefined,
110
111
  image: toolkit ? (('image_url' in toolkit ? toolkit?.image_url : toolkit?.avatar) ?? undefined) : undefined,
111
112
  goal: t.goal,
@@ -139,11 +140,18 @@ function toolsFromAgentInfo(agentInfo: any[] | null | undefined): string[] {
139
140
  */
140
141
  export async function loadChat(widget: WidgetState, conversationId: string) {
141
142
  const chat = await aiClient.chat.query({ conversationId })
142
- const historyAgentIds = chat.history?.map(item => item.custom_agent?.id).filter(Boolean) as string[] ?? []
143
+ const historyAgents = chat.history?.reduce<{ agent_core_id: string }[]>((accumulator, item) => {
144
+ const agentId = item.custom_agent?.id
145
+ if (agentId !== undefined) {
146
+ accumulator.push({ agent_core_id: agentId })
147
+ }
148
+ return accumulator
149
+ }, []) ?? []
150
+
143
151
  const [stack, workspace, agents] = await Promise.all([
144
152
  findStack(chat.ai_stack_id),
145
153
  findWorkspace(chat.workspace_id),
146
- agentToolsClient.agentsByIds.query({ searchAgentsRequest: { ids: historyAgentIds } }),
154
+ agentToolsClient.agentsByIdsV2.query({ searchAgentsRequestV2: { agents: historyAgents } }),
147
155
  ])
148
156
  const agentsAsLabeledAgents: LabeledAgent[] = agents
149
157
  .map((a) => ({ ...a, label: a.name, image: a.avatar ?? '', builtIn: a.visibility_level === 'built_in' }))
@@ -21,6 +21,7 @@ const EditorBox = styled.div`
21
21
  --vscode-editor-background: transparent !important;
22
22
  --vscode-editorGutter-background: transparent !important;
23
23
  }
24
+
24
25
  `
25
26
 
26
27
  const TitleBox = styled.div`
@@ -69,7 +70,7 @@ const Title = () => {
69
70
 
70
71
  return (
71
72
  <TitleBox>
72
- <Text appearance="h5">Editor</Text>
73
+ <Text appearance="h5" tag="h2" >Editor</Text>
73
74
  <Select
74
75
  options={languages}
75
76
  renderLabel={l => l?.label ?? defaultLanguage}
@@ -91,6 +92,22 @@ const EditorPanel = () => {
91
92
  const selectionObserver = useRef<IDisposable | undefined>()
92
93
 
93
94
  const setup: OnMount = useCallback(async (editor) => {
95
+ const container = editor.getContainerDomNode()
96
+ const el = container.querySelector('.native-edit-context')
97
+ if (el && el.hasAttribute('aria-label')) {
98
+ el.removeAttribute('aria-label')
99
+ }
100
+
101
+ const observer = new MutationObserver(() => {
102
+ const el = container.querySelector('.native-edit-context')
103
+ if (el && el.hasAttribute('aria-label')) {
104
+ el.removeAttribute('aria-label')
105
+ }
106
+ })
107
+ observer.observe(container, { subtree: true, attributes: true, childList: true })
108
+
109
+ editor.onDidDispose(() => observer.disconnect())
110
+
94
111
  selectionObserver.current = editor.onDidChangeCursorSelection(debounce((e) => {
95
112
  const selectedText = editor.getModel()?.getValueInRange(e.selection)
96
113
  chat.set('codeSelection', selectedText?.trim() ? selectedText : undefined)
@@ -110,14 +127,14 @@ const EditorPanel = () => {
110
127
  selectionObserver.current?.dispose()
111
128
  }
112
129
  }, [])
113
-
130
+
114
131
  return (
115
132
  <EditorBox>
116
133
  <MonacoEditor
117
134
  height="100%"
118
135
  language={language}
119
136
  theme={themeKind === 'dark' ? 'vs-dark' : 'light'}
120
- options={{ minimap: { enabled: false } }}
137
+ options={{ minimap: { enabled: false }, accessibilitySupport: 'off' }}
121
138
  value={value}
122
139
  onChange={v => chat.set('code', v)}
123
140
  loading={<ProgressCircular />}
@@ -11,16 +11,16 @@ import { HomeBox } from './styled'
11
11
  * This is the home rendered when the agent is custom.
12
12
  */
13
13
  export const CustomAgent = () => {
14
- const { id, label, image } = useCurrentChatState('agent') ?? {}
15
- const [agent] = agentToolsClient.agent.useStatefulQuery({ agentId: id! })
14
+ const { id, label, image, agent_version_number } = useCurrentChatState('agent') ?? {}
15
+ const [agent] = agentToolsClient.agentV2.useStatefulQuery({ agentCoreId: id!, versionNumber: agent_version_number })
16
16
  const chat = useCurrentChat()
17
- const suggestions = useMemo(() => agent?.conversation_starter?.map((prompt, index) => (
17
+ const suggestions = useMemo(() => agent?.version?.conversation_starter?.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?.version?.conversation_starter])
24
24
 
25
25
  function send(message: string) {
26
26
  chat.pushMessage(ChatEntry.createUserEntry(message))
@@ -5,16 +5,16 @@ import { VisibilityLevelEnum } from '@stack-spot/portal-network/api/agent-tools'
5
5
  import { useCallback } from 'react'
6
6
  import { Selector } from '../../components/Selector'
7
7
  import { useCurrentChat, useCurrentChatState, useWidgetState } from '../../context/hooks'
8
+ import { useIsFeatureFlagEnabled } from '../../hooks/enabled-feature-flags'
8
9
  import { agentRegex } from '../../regex'
9
10
  import { useAgentFavorites } from '../Agents/useAgentFavorites'
10
11
 
11
- type AgentWithSpaceName = AgentResponseWithBuiltIn
12
-
13
- const AgentItem = ({ avatar, name, spaceName }: AgentWithSpaceName) => {
12
+ const AgentItem = ({ avatar, name, spaceName }: AgentResponseWithBuiltIn) => {
14
13
  const avatarComponent = avatar
15
14
  ? <img style={{ width: '32px', height: '32px', borderRadius: '50%' }} src={avatar} />
16
15
  : <IconBox size="md" icon="Agent" style={{ backgroundColor: 'transparent' }} />
17
16
 
17
+
18
18
  return <Row gap="8px" style={{ flexWrap: 'nowrap' }}>
19
19
  {avatarComponent}
20
20
  <div>
@@ -31,10 +31,11 @@ export const AgentSelector = ({ inputRef, isTrial }: {
31
31
  const chat = useCurrentChat()
32
32
  const isAgentEnabled = useCurrentChatState('features').agent
33
33
  const spotId = useWidgetState('features')?.workspaceId
34
+ const featureFlag = useIsFeatureFlagEnabled('ENABLE_VERSION_CONTENT_AI')
34
35
 
35
36
  const { useFavorites, onAddFavorite, onRemoveFavorite } = useAgentFavorites()
36
37
 
37
- const onSelectItem = useCallback(async (agent: AgentResponseWithBuiltIn) => {
38
+ const onSelectItem = useCallback(async (agent: AgentResponseWithBuiltIn, selectedVersion?: number) => {
38
39
  const newValue = `@${agent.slug}`
39
40
  chat.set('nextMessage', undefined)
40
41
  chat.set(
@@ -42,10 +43,11 @@ export const AgentSelector = ({ inputRef, isTrial }: {
42
43
  {
43
44
  id: agent.id,
44
45
  label: agent.name,
45
- image: agent.avatar,
46
+ image: agent.avatar,
46
47
  slug: agent.slug,
47
48
  builtIn: agent.builtIn,
48
49
  visibility_level: agent.visibility_level,
50
+ agent_version_number: selectedVersion || agent.version_number,
49
51
  },
50
52
  )
51
53
 
@@ -70,6 +72,12 @@ export const AgentSelector = ({ inputRef, isTrial }: {
70
72
  }) }
71
73
  }
72
74
 
75
+ const getAgentVersions = (id: string, enabled: boolean) => {
76
+ const [listVersions] = agentToolsClient.listAgentVersions.useStatefulQuery({ agentCoreId: id }, { enabled })
77
+ const optionsVersions = listVersions?.map((version) => version.version_number)
78
+ return optionsVersions
79
+ }
80
+
73
81
  return <Selector
74
82
  inputRef={inputRef}
75
83
  favorite={{ useFavorites, onAddFavorite, onRemoveFavorite }}
@@ -85,8 +93,10 @@ export const AgentSelector = ({ inputRef, isTrial }: {
85
93
  ['favorite', 'personal', 'workspace', 'account', 'shared', 'built_in', 'recently_used'],
86
94
  renderComponentItem: AgentItem,
87
95
  isEnabled: isAgentEnabled,
96
+ isEnabledVersionContent: featureFlag.flagEnabled,
88
97
  onSelect: onSelectItem,
89
98
  useData: getAgents,
99
+ useVersions: getAgentVersions,
90
100
  }}
91
101
  />
92
102
  }
@@ -15,8 +15,9 @@ export const ModelSwitcher = () => {
15
15
  const chat = useCurrentChat()
16
16
  const [filter, setFilter] = useState('')
17
17
  const [visibleMenu, setVisibleMenu] = useState(false)
18
- const [agentData, isLoadingAgentData] = agentToolsClient.agent.useStatefulQuery({ agentId: agentCurrentChat?.id || '' },
19
- { enabled: !!agentCurrentChat?.id })
18
+ const [agentData, isLoadingAgentData] = agentToolsClient.agentV2.useStatefulQuery({
19
+ agentCoreId: agentCurrentChat?.id || '', versionNumber: agentCurrentChat?.agent_version_number },
20
+ { enabled: !!agentCurrentChat?.id })
20
21
  const [models, isLoadingModels] =
21
22
  genAiInferenceClient.listModels.useStatefulQuery({ pageSize: 999, active: true })
22
23
 
@@ -1,6 +1,6 @@
1
1
  import { CitricIconOutline, CitricIconSocial } from '@stack-spot/citric-icons'
2
2
  import { IconBox } from '@stack-spot/citric-react'
3
- import { AgentModel } from '@stack-spot/portal-network/api/agent-tools'
3
+ import { AgentCoreWithSingleVersionResponse2 } from '@stack-spot/portal-network/api/agent-tools'
4
4
  import { LlmModelsResponse, PaginatedResponseLlmModelsResponse } from '@stack-spot/portal-network/api/genAiInference'
5
5
  import { theme } from '@stack-spot/portal-theme'
6
6
  import { Dispatch, ReactElement } from 'react'
@@ -27,19 +27,20 @@ export const providerIcon: Record<string, CitricIconSocial | CitricIconOutline>
27
27
  export function getListModelsData(
28
28
  chat: ChatState,
29
29
  setVisibleMenu: Dispatch<React.SetStateAction<boolean>>,
30
- agent?: AgentModel,
30
+ agent?: AgentCoreWithSingleVersionResponse2,
31
31
  models?: PaginatedResponseLlmModelsResponse) {
32
32
 
33
33
  const chatSelectedModelId = chat.get('selected_model_id')
34
34
 
35
- const listModelsToShow = agent?.visibility_level !== 'built_in' && !!agent?.model_id ?
36
- models?.items.filter((model) => agent?.available_llm_models?.find((modelAvailable) => modelAvailable.model_id === model.id)) :
35
+ const listModelsToShow = agent?.visibility_level !== 'built_in' && !!agent?.version?.model_id ?
36
+ models?.items.filter((model) => agent?.version?.available_llm_models?.find((modelAvailable) => modelAvailable.model_id === model.id)) :
37
37
  models?.items
38
38
 
39
- const modelAvailableDefault = agent?.available_llm_models?.find((model) => (model.is_default || model.model_id === agent.model_id))
39
+ const modelAvailableDefault = agent?.version?.available_llm_models?.find((model) =>
40
+ (model.is_default || model.model_id === agent.version?.model_id))
40
41
  const modelListData = parseModelList(chat, setVisibleMenu, listModelsToShow, modelAvailableDefault?.model_id)
41
42
 
42
- if (agent?.visibility_level === 'built_in' || !agent?.model_id) {
43
+ if (agent?.visibility_level === 'built_in' || !agent?.version?.model_id) {
43
44
 
44
45
  const modelDefaultProviderType = models?.items.find((modelAccount) =>
45
46
  chatSelectedModelId ? modelAccount.id === chatSelectedModelId :
@@ -50,9 +51,9 @@ export function getListModelsData(
50
51
  return { modelName: modelDefaultActive?.label, modelProviderType: modelDefaultProviderType, listItemsData: modelListData }
51
52
  }
52
53
 
53
- const modelAccount = models?.items.find((modelAccount) => modelAccount.id === (chatSelectedModelId || agent.model_id))
54
+ const modelAccount = models?.items.find((modelAccount) => modelAccount.id === (chatSelectedModelId || agent.version?.model_id))
54
55
  const modelProviderType = modelAccount?.model_configuration.provider.provider_type
55
- const modelSelectedName = modelAccount?.display_name || modelAvailableDefault?.model_name || agent?.model_name
56
+ const modelSelectedName = modelAccount?.display_name || modelAvailableDefault?.model_name || agent?.version?.model_name
56
57
 
57
58
  const listItemsData =
58
59
  modelListData && modelListData?.length > 0 ? modelListData :
@@ -46,15 +46,19 @@ const ResourcesPanel = () => {
46
46
  const chat = widget.chatTabs.getAll().find(c => c.id === chatId)
47
47
  return chat?.getMessages().find(m => m.id === messageId)?.getValue()
48
48
  }, [messageId])
49
- const [agent] = agentToolsClient.agent.useStatefulQuery({ agentId: message?.agent?.id || '' },
50
- { enabled: !!message?.agent?.id })
49
+
50
+ const [agent] = agentToolsClient.agentV2.useStatefulQuery({
51
+ agentCoreId: message?.agent?.id || '', versionNumber: message?.agent?.agent_version_number },
52
+ { enabled: !!message?.agent?.id })
51
53
  const toolkits = useMemo(() => [
52
- ...agent?.toolkits?.builtin_toolkits ?? [],
53
- ...agent?.toolkits?.custom_toolkits ?? [],
54
- ...agent?.toolkits?.mcp_toolkits ?? [],
54
+ ...agent?.version?.toolkits?.builtin_toolkits ?? [],
55
+ ...agent?.version?.toolkits?.custom_toolkits ?? [],
56
+ ...agent?.version?.toolkits?.mcp_toolkits ?? [],
55
57
  ], [agent])
56
58
  const tools = useMemo(() => message?.tools?.map(id => toolById(id, toolkits)), [messageId, toolkits])
57
- const [agentsTools] = agentToolsClient.agentsByIds.useStatefulQuery({ searchAgentsRequest:{ ids: message?.tools || [] } })
59
+ const agentsSearch = message?.tools?.map((id) => ({ agent_core_id: id })) ?? []
60
+ const [agentsTools] = agentToolsClient.agentsByIdsV2.useStatefulQuery(
61
+ { searchAgentsRequestV2: { agents: agentsSearch } })
58
62
  const hasAgentTool = useMemo(() => message?.tools?.some(id => agentsTools?.find((agent) => agent.id === id)), [messageId])
59
63
 
60
64
  const header = (image?: string, label?: string) => (
@@ -42,11 +42,12 @@ const ToolsPanel = () => {
42
42
  }, [messageId])
43
43
 
44
44
  const [toolKits] = agentToolsClient.tools.useStatefulQuery({}, { enabled: !!message?.agent?.id })
45
- const [agent] = agentToolsClient.agent.useStatefulQuery({ agentId: message?.agent?.id || '' },
46
- { enabled: !!message?.agent?.id })
45
+ const [agent] = agentToolsClient.agentV2.useStatefulQuery({ agentCoreId: message?.agent?.id || '',
46
+ versionNumber: message?.agent?.agent_version_number },
47
+ { enabled: !!message?.agent?.id })
47
48
  const tools = useMemo(() => message?.tools?.map(id => toolById(id, toolKits)), [messageId, toolKits])
48
- const customTools = useMemo(() => message?.tools?.map(id => toolById(id, agent?.toolkits?.custom_toolkits)),
49
- [messageId, agent?.toolkits?.custom_toolkits])
49
+ const customTools = useMemo(() => message?.tools?.map(id => toolById(id, agent?.version?.toolkits?.custom_toolkits)),
50
+ [messageId, agent?.version?.toolkits?.custom_toolkits])
50
51
  return !!(tools?.length || customTools?.length) && (
51
52
  <ToolList>
52
53
  {[...(tools || []), ...(customTools || [])].map(