@stack-spot/ai-chat-widget 1.36.2-beta.1 → 1.36.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 (64) hide show
  1. package/CHANGELOG.md +33 -22
  2. package/dist/app-metadata.json +4 -4
  3. package/dist/chat-interceptors/quick-commands.d.ts.map +1 -1
  4. package/dist/chat-interceptors/quick-commands.js +9 -3
  5. package/dist/chat-interceptors/quick-commands.js.map +1 -1
  6. package/dist/components/FileDescription.js +1 -1
  7. package/dist/components/FileDescription.js.map +1 -1
  8. package/dist/components/HistoryList.d.ts.map +1 -1
  9. package/dist/components/HistoryList.js +2 -0
  10. package/dist/components/HistoryList.js.map +1 -1
  11. package/dist/hooks/midnight-update-view.d.ts +5 -0
  12. package/dist/hooks/midnight-update-view.d.ts.map +1 -0
  13. package/dist/hooks/midnight-update-view.js +30 -0
  14. package/dist/hooks/midnight-update-view.js.map +1 -0
  15. package/dist/index.d.ts +1 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +1 -1
  18. package/dist/index.js.map +1 -1
  19. package/dist/layout.css +1 -1
  20. package/dist/state/constants.js +2 -2
  21. package/dist/state/constants.js.map +1 -1
  22. package/dist/utils/tools.d.ts +2 -1
  23. package/dist/utils/tools.d.ts.map +1 -1
  24. package/dist/utils/tools.js +12 -1
  25. package/dist/utils/tools.js.map +1 -1
  26. package/dist/utils/upload/FileUpload.d.ts.map +1 -1
  27. package/dist/utils/upload/FileUpload.js +1 -2
  28. package/dist/utils/upload/FileUpload.js.map +1 -1
  29. package/dist/views/Chat/ChatMessage.d.ts.map +1 -1
  30. package/dist/views/Chat/ChatMessage.js +2 -0
  31. package/dist/views/Chat/ChatMessage.js.map +1 -1
  32. package/dist/views/MessageInput/ContextBar.js +1 -1
  33. package/dist/views/MessageInput/ContextBar.js.map +1 -1
  34. package/dist/views/MessageInput/SelectContent.d.ts.map +1 -1
  35. package/dist/views/MessageInput/SelectContent.js +8 -8
  36. package/dist/views/MessageInput/SelectContent.js.map +1 -1
  37. package/dist/views/MessageInput/UploadBar.d.ts.map +1 -1
  38. package/dist/views/MessageInput/UploadBar.js +0 -5
  39. package/dist/views/MessageInput/UploadBar.js.map +1 -1
  40. package/dist/views/MessageInput/dictionary.d.ts +1 -1
  41. package/dist/views/MessageInput/dictionary.d.ts.map +1 -1
  42. package/dist/views/MessageInput/dictionary.js +2 -0
  43. package/dist/views/MessageInput/dictionary.js.map +1 -1
  44. package/dist/views/MessageInput/styled.js +8 -8
  45. package/dist/views/Tools.js +4 -2
  46. package/dist/views/Tools.js.map +1 -1
  47. package/package.json +3 -3
  48. package/src/app-metadata.json +4 -4
  49. package/src/chat-interceptors/quick-commands.ts +11 -5
  50. package/src/components/FileDescription.tsx +1 -1
  51. package/src/components/HistoryList.tsx +3 -0
  52. package/src/hooks/midnight-update-view.ts +36 -0
  53. package/src/index.ts +1 -2
  54. package/src/layout.css +1 -1
  55. package/src/state/constants.ts +2 -2
  56. package/src/utils/tools.ts +23 -2
  57. package/src/utils/upload/FileUpload.ts +1 -2
  58. package/src/views/Chat/ChatMessage.tsx +2 -0
  59. package/src/views/MessageInput/ContextBar.tsx +1 -1
  60. package/src/views/MessageInput/SelectContent.tsx +10 -11
  61. package/src/views/MessageInput/UploadBar.tsx +3 -9
  62. package/src/views/MessageInput/dictionary.ts +2 -0
  63. package/src/views/MessageInput/styled.ts +8 -8
  64. package/src/views/Tools.tsx +19 -13
@@ -12,6 +12,7 @@ import { FileDescription } from '../../components/FileDescription'
12
12
  import { Markdown } from '../../components/Markdown'
13
13
  import { StackedBadge } from '../../components/StackedBadge'
14
14
  import { useChatEntry, useCurrentChat, useWidget } from '../../context/hooks'
15
+ import { useMidnightUpdateView } from '../../hooks/midnight-update-view'
15
16
  import { ChatEntry, SerializableAction, TextChatEntry } from '../../state/ChatEntry'
16
17
  import { useDateFormatter } from '../../utils/date'
17
18
  import { toolById } from '../../utils/tools'
@@ -198,6 +199,7 @@ export const ChatMessage = ({ message, isLast, beforeMessage, afterMessage }: Pr
198
199
  const [showUserButtonCopy, setShowUserButtonCopy] = useState(false)
199
200
 
200
201
  useChatScrollToBottomEffect(ref, [entry])
202
+ useMidnightUpdateView()
201
203
 
202
204
  const detailKS = useCallback(({ name, slug, documentScore, documentId }: Required<TextChatEntry>['knowledgeSources'][number]) => {
203
205
  widget.set('currentKSInPanel', { name, slug, score: documentScore, documentId })
@@ -19,7 +19,7 @@ const ContextBadge = ({ label, color, dismiss, onDismiss }: ContextBadgeProps) =
19
19
  <Badge appearance="square" palette={color} className="context-badge"
20
20
  afterElement={
21
21
  onDismiss &&
22
- <IconButton appearance="square" colorIcon={`${color}.800`} onClick={onDismiss} title={dismiss} arial-label={dismiss}>
22
+ <IconButton appearance="square" colorIcon={`${color}.800`} onClick={onDismiss} title={dismiss} aria-label={dismiss}>
23
23
  <TimesMini />
24
24
  </IconButton>
25
25
  }>
@@ -20,53 +20,53 @@ export const SelectContent = () => {
20
20
 
21
21
  const itemConfigs = [
22
22
  {
23
+ role: 'button',
23
24
  key: 'agent',
24
25
  label: t.chatAgent,
25
26
  icon: <Agent />,
26
- 'aria-label': 'Botão de agent',
27
27
  onClick: (event?: React.MouseEvent) => {
28
28
  event?.stopPropagation()
29
29
  chat.set('nextMessage', '@')
30
30
  },
31
31
  },
32
32
  {
33
+ role: 'button',
33
34
  key: 'quickCommands',
34
35
  label: 'Quick Commands',
35
36
  icon: <QuickCommand />,
36
- 'aria-label': 'Botão de quickCommands',
37
37
  onClick: (event?: React.MouseEvent) => {
38
38
  event?.stopPropagation()
39
39
  chat.set('nextMessage', '/')
40
40
  },
41
41
  },
42
42
  {
43
+ role: 'button',
43
44
  key: 'knowledgeSource',
44
45
  label: 'Knowledge Sources',
45
46
  icon: <KnowledgeSource />,
46
- 'aria-label': 'Botão de knowledgeSource',
47
47
  panel: 'ks',
48
48
  },
49
49
  {
50
+ role: 'button',
50
51
  key: 'stack',
51
52
  label: 'Stacks AI',
52
53
  icon: <Stack />,
53
- 'aria-label': 'Botão de stack',
54
54
  panel: 'stack',
55
55
  },
56
56
  {
57
+ role: 'button',
57
58
  key: 'workspace',
58
59
  label: 'Spots',
59
60
  icon: <Spaces />,
60
- 'aria-label': 'Botão de workspace',
61
61
  panel: 'workspace',
62
62
  },
63
63
  {
64
+ role: 'button',
64
65
  key: 'upload',
65
66
  label: t.upload,
66
67
  onClick: () => uploadManager.open(),
67
68
  className: 'upload-item',
68
69
  icon: <DocumentUpload />,
69
- 'aria-label': 'Botão de upload de arquivos',
70
70
  },
71
71
  ]
72
72
 
@@ -80,7 +80,7 @@ export const SelectContent = () => {
80
80
  widget.set('panel', chatFeatures.panel as ChatPanel)
81
81
  setVisibleMenu(false)
82
82
  }) : chatFeatures.onClick,
83
- 'aria-label': chatFeatures['aria-label'],
83
+ role: chatFeatures.role,
84
84
  })), [features, widget])
85
85
 
86
86
  if (!hasFeatureButtons) return null
@@ -91,10 +91,9 @@ export const SelectContent = () => {
91
91
  id="button-content-select"
92
92
  color="light"
93
93
  appearance="square"
94
- role="button"
95
- title={visibleMenu ? t.collapse : t.expand}
94
+ title={t.chatViewMenu}
96
95
  data-test-hint="button-options"
97
- aria-label={visibleMenu ? t.collapse : t.expand}
96
+ aria-label={t.chatViewMenu}
98
97
  aria-controls="chatMessageMenu"
99
98
  aria-expanded={visibleMenu}
100
99
  onClick={() => setVisibleMenu(state => !state)}>
@@ -106,7 +105,7 @@ export const SelectContent = () => {
106
105
  visible={visibleMenu}
107
106
  onHide={() => setVisibleMenu(false)}
108
107
  items={listItems}
109
- aria-label="Menu de opções do chat"
108
+ aria-label={t.chatViewMenu}
110
109
  />
111
110
  </>
112
111
  ) : (
@@ -22,6 +22,7 @@ const UploadItem = ({ upload }: UploadedFileProps) => {
22
22
  const uploadManager = useUploadManager()
23
23
  const icon = upload.file.type.toLowerCase().startsWith('image/') ? createImageFromFile(upload.file) : undefined
24
24
  const status = useUploadStatus(upload)
25
+
25
26
  return <FileDescription
26
27
  fileName={upload.file.name}
27
28
  icon={icon}
@@ -39,7 +40,7 @@ export const UploadBar = () => {
39
40
  const visible = !!uploads.length
40
41
  const [ariaMessage, setAriaMessage] = useState('')
41
42
  const prevUploadsRef = useRef<FileUpload[]>([])
42
- const announcedUploadsRef = useRef<Set<string>>(new Set())
43
+ const announcedUploadsRef = useRef(new Set())
43
44
 
44
45
  useEffect(() => {
45
46
  const prevUploads = prevUploadsRef.current
@@ -79,15 +80,8 @@ export const UploadBar = () => {
79
80
  setAriaMessage(lines.join(' '))
80
81
  setTimeout(() => setAriaMessage(''), 2000)
81
82
  chat.pushMessage(new ChatEntry({ agentType: 'system', type: 'md', content: lines.join('\n\n') }))
82
-
83
- if (lines.length) {
84
- setAriaMessage(lines.join(' '))
85
- setTimeout(() => setAriaMessage(''), 2000)
86
- chat.pushMessage(new ChatEntry({ agentType: 'system', type: 'md', content: lines.join('\n\n') }))
87
- }
88
83
  })
89
-
90
-
84
+
91
85
  return (
92
86
  <div className={listToClass(['info-bar', 'upload-bar', visible && 'visible'])}>
93
87
  <div className="aria-live"
@@ -34,6 +34,7 @@ const dictionary = {
34
34
  cantSendBecausePromptMaxLength: 'You can\'t send messages longer than $0 characters. Please, shorten your message.',
35
35
  chatAgent: 'Agents',
36
36
  uploadSuccessStatus: 'File sent successfully',
37
+ chatViewMenu: 'Chat options menu',
37
38
  },
38
39
  pt: {
39
40
  stack: 'Selecionar stack',
@@ -68,6 +69,7 @@ const dictionary = {
68
69
  cantSendBecausePromptMaxLength: 'Você não pode enviar mensagens com mais de $0 caracteres. Por favor, reduza sua mensagem.',
69
70
  chatAgent: 'Agentes',
70
71
  uploadSuccessStatus: 'Arquivo anexado com sucesso',
72
+ chatViewMenu: 'Menu de opções do chat',
71
73
  },
72
74
  } satisfies Dictionary
73
75
 
@@ -67,14 +67,14 @@ export const MessageInputBox = styled.div<{$inputFocused?: boolean}>`
67
67
 
68
68
  > .aria-live {
69
69
  position: absolute;
70
- width: 1;
71
- height: 1;
72
- margin: -1;
73
- padding: 0;
74
- overflow: hidden;
75
- clip: rect(0 0 0 0);
76
- white-Space: nowrap;
77
- border: 0;
70
+ width: 1px;
71
+ height: 1px;
72
+ margin: -1px;
73
+ padding: 0;
74
+ overflow: hidden;
75
+ clip: rect(0 0 0 0);
76
+ white-space: nowrap;
77
+ border: 0;
78
78
  }
79
79
 
80
80
  > .space {
@@ -42,20 +42,26 @@ const ToolsPanel = () => {
42
42
  }, [messageId])
43
43
 
44
44
  const [toolKits] = agentToolsClient.tools.useStatefulQuery({}, { enabled: !!message?.agent?.id })
45
- const tools = useMemo(() => message?.tools?.map(id => toolById(id, toolKits) ?? { id }), [messageId, toolKits])
46
-
47
- return !!tools?.length && (
45
+ const [agent] = agentToolsClient.agent.useStatefulQuery({ agentId: message?.agent?.id || '' },
46
+ { enabled: !!message?.agent?.id })
47
+ 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])
50
+ return !!(tools?.length || customTools?.length) && (
48
51
  <ToolList>
49
- {tools.map((tool) => (
50
- <li key={tool.id}>
51
- <ToolBadge
52
- name={tool.name || tool.id}
53
- image={tool.image}
54
- description={tool.description}
55
- backgroundColor="light.500"
56
- />
57
- </li>
58
- ))}
52
+ {[...(tools || []), ...(customTools || [])].map(
53
+ (tool) =>
54
+ tool && (
55
+ <li key={tool.id}>
56
+ <ToolBadge
57
+ name={tool.name || tool.id}
58
+ image={tool.image ?? ''}
59
+ description={tool.description ?? ''}
60
+ backgroundColor="light.500"
61
+ />
62
+ </li>
63
+ ),
64
+ )}
59
65
  </ToolList>
60
66
  )
61
67
  }