@stack-spot/ai-chat-widget 2.12.2 → 2.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/app-metadata.json +3 -3
  3. package/dist/components/Selector/SelectVersion.d.ts +12 -0
  4. package/dist/components/Selector/SelectVersion.d.ts.map +1 -0
  5. package/dist/components/Selector/SelectVersion.js +33 -0
  6. package/dist/components/Selector/SelectVersion.js.map +1 -0
  7. package/dist/components/Selector/index.d.ts +3 -1
  8. package/dist/components/Selector/index.d.ts.map +1 -1
  9. package/dist/components/Selector/index.js +10 -7
  10. package/dist/components/Selector/index.js.map +1 -1
  11. package/dist/components/Selector/styled.d.ts +2 -0
  12. package/dist/components/Selector/styled.d.ts.map +1 -1
  13. package/dist/components/Selector/styled.js +45 -0
  14. package/dist/components/Selector/styled.js.map +1 -1
  15. package/dist/hooks/enabled-feature-flags.d.ts +5 -0
  16. package/dist/hooks/enabled-feature-flags.d.ts.map +1 -0
  17. package/dist/hooks/enabled-feature-flags.js +28 -0
  18. package/dist/hooks/enabled-feature-flags.js.map +1 -0
  19. package/dist/state/types.d.ts +1 -0
  20. package/dist/state/types.d.ts.map +1 -1
  21. package/dist/utils/chat.d.ts.map +1 -1
  22. package/dist/utils/chat.js +1 -0
  23. package/dist/utils/chat.js.map +1 -1
  24. package/dist/utils/tools.d.ts +5 -5
  25. package/dist/utils/tools.d.ts.map +1 -1
  26. package/dist/utils/tools.js +2 -2
  27. package/dist/utils/tools.js.map +1 -1
  28. package/dist/views/Agents/AgentDescription.d.ts +6 -2
  29. package/dist/views/Agents/AgentDescription.d.ts.map +1 -1
  30. package/dist/views/Agents/AgentDescription.js +25 -10
  31. package/dist/views/Agents/AgentDescription.js.map +1 -1
  32. package/dist/views/Agents/AgentsTab.d.ts.map +1 -1
  33. package/dist/views/Agents/AgentsTab.js +21 -4
  34. package/dist/views/Agents/AgentsTab.js.map +1 -1
  35. package/dist/views/Agents/dictionary.d.ts +1 -1
  36. package/dist/views/Agents/dictionary.d.ts.map +1 -1
  37. package/dist/views/Agents/dictionary.js +2 -0
  38. package/dist/views/Agents/dictionary.js.map +1 -1
  39. package/dist/views/Chat/ChatMessage.d.ts.map +1 -1
  40. package/dist/views/Chat/ChatMessage.js +6 -5
  41. package/dist/views/Chat/ChatMessage.js.map +1 -1
  42. package/dist/views/ChatHistory/utils.d.ts.map +1 -1
  43. package/dist/views/ChatHistory/utils.js +20 -10
  44. package/dist/views/ChatHistory/utils.js.map +1 -1
  45. package/dist/views/Home/CustomAgent.js +3 -3
  46. package/dist/views/Home/CustomAgent.js.map +1 -1
  47. package/dist/views/MessageInput/AgentSelector.d.ts.map +1 -1
  48. package/dist/views/MessageInput/AgentSelector.js +13 -3
  49. package/dist/views/MessageInput/AgentSelector.js.map +1 -1
  50. package/dist/views/MessageInput/ModelSwitcher/index.d.ts.map +1 -1
  51. package/dist/views/MessageInput/ModelSwitcher/index.js +3 -1
  52. package/dist/views/MessageInput/ModelSwitcher/index.js.map +1 -1
  53. package/dist/views/MessageInput/ModelSwitcher/utils.d.ts +2 -2
  54. package/dist/views/MessageInput/ModelSwitcher/utils.d.ts.map +1 -1
  55. package/dist/views/MessageInput/ModelSwitcher/utils.js +6 -6
  56. package/dist/views/MessageInput/ModelSwitcher/utils.js.map +1 -1
  57. package/dist/views/Resources.js +8 -5
  58. package/dist/views/Resources.js.map +1 -1
  59. package/dist/views/Tools.js +3 -2
  60. package/dist/views/Tools.js.map +1 -1
  61. package/package.json +2 -2
  62. package/src/app-metadata.json +3 -3
  63. package/src/components/Selector/SelectVersion.tsx +55 -0
  64. package/src/components/Selector/index.tsx +20 -11
  65. package/src/components/Selector/styled.ts +47 -0
  66. package/src/hooks/enabled-feature-flags.ts +31 -0
  67. package/src/state/types.ts +1 -0
  68. package/src/utils/chat.ts +1 -0
  69. package/src/utils/tools.ts +4 -4
  70. package/src/views/Agents/AgentDescription.tsx +48 -14
  71. package/src/views/Agents/AgentsTab.tsx +31 -13
  72. package/src/views/Agents/dictionary.ts +2 -1
  73. package/src/views/Chat/ChatMessage.tsx +8 -6
  74. package/src/views/ChatHistory/utils.ts +25 -13
  75. package/src/views/Home/CustomAgent.tsx +4 -4
  76. package/src/views/MessageInput/AgentSelector.tsx +17 -7
  77. package/src/views/MessageInput/ModelSwitcher/index.tsx +3 -2
  78. package/src/views/MessageInput/ModelSwitcher/utils.tsx +9 -8
  79. package/src/views/Resources.tsx +10 -6
  80. package/src/views/Tools.tsx +5 -4
@@ -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,9 @@ 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
+ agent = agentId ? await agentToolsClient.agentV2.query({ agentCoreId: agentId }) : undefined
81
81
  } catch { /* empty */ }
82
82
  const planning: PlanningChatStep = {
83
83
  type: 'planning',
@@ -105,7 +105,7 @@ async function stepsFromAgentInfo(
105
105
  return {
106
106
  id: t.tool_id,
107
107
  executionId: t.tool_execution_id,
108
- name: tool?.name,
108
+ name: ('name' in tool ? tool.name : ('function' in tool ? tool?.function?.name : undefined) ?? ''),
109
109
  description: 'description' in tool ? tool.description : undefined,
110
110
  image: toolkit ? (('image_url' in toolkit ? toolkit?.image_url : toolkit?.avatar) ?? undefined) : undefined,
111
111
  goal: t.goal,
@@ -139,21 +139,33 @@ function toolsFromAgentInfo(agentInfo: any[] | null | undefined): string[] {
139
139
  */
140
140
  export async function loadChat(widget: WidgetState, conversationId: string) {
141
141
  const chat = await aiClient.chat.query({ conversationId })
142
- const historyAgentIds = chat.history?.map(item => item.custom_agent?.id).filter(Boolean) as string[] ?? []
142
+ const addedIds: Record<string, boolean> = {}
143
+ const historyAgents = chat.history?.reduce<{ agent_core_id: string, version_number?: number }[]>((accumulator, item) => {
144
+ const agentId = item.custom_agent?.id
145
+ if (agentId !== undefined && !addedIds[agentId]) {
146
+ addedIds[agentId] = true
147
+ accumulator.push({ agent_core_id: agentId, version_number: item.custom_agent?.version_number })
148
+ }
149
+ return accumulator
150
+ }, []) ?? []
151
+
143
152
  const [stack, workspace, agents] = await Promise.all([
144
153
  findStack(chat.ai_stack_id),
145
154
  findWorkspace(chat.workspace_id),
146
- agentToolsClient.agentsByIds.query({ searchAgentsRequest: { ids: historyAgentIds } }),
155
+ agentToolsClient.agentsByIdsV2.query({ searchAgentsRequestV2: { agents: historyAgents } }),
147
156
  ])
148
157
  const agentsAsLabeledAgents: LabeledAgent[] = agents
149
158
  .map((a) => ({ ...a, label: a.name, image: a.avatar ?? '', builtIn: a.visibility_level === 'built_in' }))
150
-
159
+
151
160
  const agent = agentsAsLabeledAgents.find(a => a.id === last(chat.history)?.custom_agent?.id)
152
161
  const builtIn = !!last(chat.history ?? [])?.custom_agent?.built_in
153
162
  widget.chatTabs.add(new ChatState({
154
163
  id: chat.id,
155
- initial: { features: widget.chatFeatures, label: chat.title, stack, workspace, agent: agent ? {
156
- ...agent, builtIn } : undefined },
164
+ initial: {
165
+ features: widget.chatFeatures, label: chat.title, stack, workspace, agent: agent ? {
166
+ ...agent, builtIn,
167
+ } : undefined,
168
+ },
157
169
  interceptors: widget.interceptors,
158
170
  entries: await Promise.all(chat.history?.map(async (item, index) => new ChatEntry({
159
171
  agentType: item.agent === 'USER' ? 'user' : 'bot',
@@ -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 }}
@@ -81,12 +89,14 @@ export const AgentSelector = ({ inputRef, isTrial }: {
81
89
  urlBuilder: (agent) => `/agents/${agent?.id}`,
82
90
  searchProp: 'name',
83
91
  sections: isTrial ?
84
- ['favorite', 'personal', 'built_in', 'recently_used'] :
85
- ['favorite', 'personal', 'workspace', 'account', 'shared', 'built_in', 'recently_used'],
92
+ ['recently_used', 'favorite', 'personal', 'built_in'] :
93
+ ['recently_used', 'favorite', 'personal', 'workspace', 'account', 'shared', 'built_in'],
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(