@stack-spot/ai-chat-widget 1.24.3 → 1.25.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 (108) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/app-metadata.json +3 -3
  3. package/dist/chat-interceptors/send-message.js +3 -3
  4. package/dist/chat-interceptors/send-message.js.map +1 -1
  5. package/dist/components/FileDescription.d.ts +10 -0
  6. package/dist/components/FileDescription.d.ts.map +1 -0
  7. package/dist/components/FileDescription.js +85 -0
  8. package/dist/components/FileDescription.js.map +1 -0
  9. package/dist/state/ChatEntry.d.ts +9 -0
  10. package/dist/state/ChatEntry.d.ts.map +1 -1
  11. package/dist/state/ChatEntry.js.map +1 -1
  12. package/dist/state/ChatState.d.ts +5 -0
  13. package/dist/state/ChatState.d.ts.map +1 -1
  14. package/dist/state/ChatState.js +6 -0
  15. package/dist/state/ChatState.js.map +1 -1
  16. package/dist/state/constants.d.ts +5 -0
  17. package/dist/state/constants.d.ts.map +1 -0
  18. package/dist/state/constants.js +9 -0
  19. package/dist/state/constants.js.map +1 -0
  20. package/dist/state/types.d.ts +4 -0
  21. package/dist/state/types.d.ts.map +1 -1
  22. package/dist/utils/chat.d.ts +2 -1
  23. package/dist/utils/chat.d.ts.map +1 -1
  24. package/dist/utils/chat.js +2 -1
  25. package/dist/utils/chat.js.map +1 -1
  26. package/dist/utils/upload/FileUpload.d.ts +21 -0
  27. package/dist/utils/upload/FileUpload.d.ts.map +1 -0
  28. package/dist/utils/upload/FileUpload.js +55 -0
  29. package/dist/utils/upload/FileUpload.js.map +1 -0
  30. package/dist/utils/upload/UploadManager.d.ts +40 -0
  31. package/dist/utils/upload/UploadManager.d.ts.map +1 -0
  32. package/dist/utils/upload/UploadManager.js +131 -0
  33. package/dist/utils/upload/UploadManager.js.map +1 -0
  34. package/dist/utils/upload/context.d.ts +15 -0
  35. package/dist/utils/upload/context.d.ts.map +1 -0
  36. package/dist/utils/upload/context.js +37 -0
  37. package/dist/utils/upload/context.js.map +1 -0
  38. package/dist/utils/upload/errors.d.ts +17 -0
  39. package/dist/utils/upload/errors.d.ts.map +1 -0
  40. package/dist/utils/upload/errors.js +27 -0
  41. package/dist/utils/upload/errors.js.map +1 -0
  42. package/dist/utils/upload/types.d.ts +7 -0
  43. package/dist/utils/upload/types.d.ts.map +1 -0
  44. package/dist/utils/upload/types.js +2 -0
  45. package/dist/utils/upload/types.js.map +1 -0
  46. package/dist/utils/upload/utils.d.ts +4 -0
  47. package/dist/utils/upload/utils.d.ts.map +1 -0
  48. package/dist/utils/upload/utils.js +10 -0
  49. package/dist/utils/upload/utils.js.map +1 -0
  50. package/dist/views/Chat/AgentInfo.d.ts +2 -1
  51. package/dist/views/Chat/AgentInfo.d.ts.map +1 -1
  52. package/dist/views/Chat/AgentInfo.js +2 -2
  53. package/dist/views/Chat/AgentInfo.js.map +1 -1
  54. package/dist/views/Chat/ChatMessage.d.ts +1 -1
  55. package/dist/views/Chat/ChatMessage.d.ts.map +1 -1
  56. package/dist/views/Chat/ChatMessage.js +26 -7
  57. package/dist/views/Chat/ChatMessage.js.map +1 -1
  58. package/dist/views/Chat/styled.d.ts.map +1 -1
  59. package/dist/views/Chat/styled.js +23 -1
  60. package/dist/views/Chat/styled.js.map +1 -1
  61. package/dist/views/MessageInput/{InfoBar.d.ts → ContextBar.d.ts} +2 -2
  62. package/dist/views/MessageInput/ContextBar.d.ts.map +1 -0
  63. package/dist/views/MessageInput/{InfoBar.js → ContextBar.js} +5 -5
  64. package/dist/views/MessageInput/ContextBar.js.map +1 -0
  65. package/dist/views/MessageInput/SelectContent.d.ts.map +1 -1
  66. package/dist/views/MessageInput/SelectContent.js +14 -17
  67. package/dist/views/MessageInput/SelectContent.js.map +1 -1
  68. package/dist/views/MessageInput/UploadBar.d.ts +2 -0
  69. package/dist/views/MessageInput/UploadBar.d.ts.map +1 -0
  70. package/dist/views/MessageInput/UploadBar.js +47 -0
  71. package/dist/views/MessageInput/UploadBar.js.map +1 -0
  72. package/dist/views/MessageInput/dictionary.d.ts +1 -1
  73. package/dist/views/MessageInput/dictionary.d.ts.map +1 -1
  74. package/dist/views/MessageInput/dictionary.js +18 -4
  75. package/dist/views/MessageInput/dictionary.js.map +1 -1
  76. package/dist/views/MessageInput/index.d.ts.map +1 -1
  77. package/dist/views/MessageInput/index.js +46 -5
  78. package/dist/views/MessageInput/index.js.map +1 -1
  79. package/dist/views/MessageInput/styled.d.ts.map +1 -1
  80. package/dist/views/MessageInput/styled.js +56 -27
  81. package/dist/views/MessageInput/styled.js.map +1 -1
  82. package/dist/views/Steps/dictionary.d.ts +1 -1
  83. package/package.json +2 -2
  84. package/src/app-metadata.json +3 -3
  85. package/src/chat-interceptors/send-message.ts +3 -3
  86. package/src/components/FileDescription.tsx +114 -0
  87. package/src/state/ChatEntry.ts +10 -0
  88. package/src/state/ChatState.ts +6 -0
  89. package/src/state/constants.ts +12 -0
  90. package/src/state/types.ts +5 -0
  91. package/src/utils/chat.ts +3 -1
  92. package/src/utils/upload/FileUpload.ts +64 -0
  93. package/src/utils/upload/UploadManager.ts +147 -0
  94. package/src/utils/upload/context.tsx +44 -0
  95. package/src/utils/upload/errors.ts +34 -0
  96. package/src/utils/upload/types.ts +7 -0
  97. package/src/utils/upload/utils.ts +12 -0
  98. package/src/views/Chat/AgentInfo.tsx +3 -2
  99. package/src/views/Chat/ChatMessage.tsx +139 -113
  100. package/src/views/Chat/styled.ts +23 -1
  101. package/src/views/MessageInput/{InfoBar.tsx → ContextBar.tsx} +9 -9
  102. package/src/views/MessageInput/SelectContent.tsx +17 -21
  103. package/src/views/MessageInput/UploadBar.tsx +69 -0
  104. package/src/views/MessageInput/dictionary.ts +18 -4
  105. package/src/views/MessageInput/index.tsx +77 -32
  106. package/src/views/MessageInput/styled.ts +56 -27
  107. package/dist/views/MessageInput/InfoBar.d.ts.map +0 -1
  108. package/dist/views/MessageInput/InfoBar.js.map +0 -1
@@ -7,14 +7,16 @@ import { useCurrentChat, useCurrentChatState, useWidgetState } from '../../conte
7
7
  import { quickCommandRegex } from '../../regex'
8
8
  import { ChatEntry } from '../../state/ChatEntry'
9
9
  import { checkIsTrial } from '../../utils/check-is-trial'
10
+ import { UploadProvider } from '../../utils/upload/context'
10
11
  import { AgentSelector } from './AgentSelector'
11
12
  import { ButtonAgent } from './ButtonAgent'
12
13
  import { ButtonBar } from './ButtonBar'
13
14
  import { useUserEntryHistoryShortcut } from './chat-entry-history'
15
+ import { ContextBar } from './ContextBar'
14
16
  import { useMessageInputDictionary } from './dictionary'
15
- import { InfoBar } from './InfoBar'
16
17
  import { QuickCommandSelector } from './QuickCommandSelector'
17
18
  import { MAX_INPUT_HEIGHT, MessageInputBox, MIN_INPUT_HEIGHT } from './styled'
19
+ import { UploadBar } from './UploadBar'
18
20
 
19
21
  /**
20
22
  * This renders the MessageInput part of the layout which includes the progress bar, the actual textarea, the badges telling what is
@@ -35,14 +37,56 @@ export const MessageInput = () => {
35
37
  const { handleKeyDown, handleKeyUp } = useUserEntryHistoryShortcut()
36
38
  const isTrial = checkIsTrial()
37
39
 
40
+ const checkSendRequirements = useCallback(() => {
41
+ if (chat.uploadManager.status === 'error') {
42
+ chat.pushMessage(new ChatEntry({
43
+ agentType: 'system',
44
+ type: 'text',
45
+ content: t.cantSendBecauseOfUploadError,
46
+ }))
47
+ return false
48
+ }
49
+ if (chat.uploadManager.status === 'uploading') {
50
+ chat.pushMessage(new ChatEntry({
51
+ agentType: 'system',
52
+ type: 'text',
53
+ content: t.cantSendBecauseOfUploadProgress,
54
+ }))
55
+ return false
56
+ }
57
+ if (!chat.get('nextMessage') && !chat.uploadManager.get().length) {
58
+ chat.pushMessage(new ChatEntry({
59
+ agentType: 'system',
60
+ type: 'text',
61
+ content: t.cantSendBecauseOfEmptyContent,
62
+ }))
63
+ return false
64
+ }
65
+ return true
66
+ }, [chat])
67
+
38
68
  const onSend = useCallback(async () => {
39
- const message = chat.get('nextMessage')
40
- if (!message) return
69
+ const message = chat.get('nextMessage')
70
+ const canSend = checkSendRequirements()
71
+ if (!canSend) return
41
72
  const code = chat.get('codeSelection')
42
73
  const language = chat.get('codeLanguage')
43
- const prompt = code && !quickCommandRegex.test(message) ? `${message}\n\`\`\`${language}\n${code}\n\`\`\`` : message
44
- chat.pushMessage(ChatEntry.createUserEntry(prompt, true))
74
+ const prompt = code && !quickCommandRegex.test(message ?? '') ? `${message}\n\`\`\`${language}\n${code}\n\`\`\`` : message
75
+ chat.pushMessage(new ChatEntry({
76
+ type: 'md',
77
+ agentType: 'user',
78
+ content: prompt || '',
79
+ upload: chat.uploadManager.get().map(
80
+ up => ({
81
+ id: up.uploadId!, // we know that all files have been uploaded, so they have an id
82
+ name: up.file.name,
83
+ image: up.file.type.toLowerCase().startsWith('image/') ? URL.createObjectURL(up.file) : undefined,
84
+ }),
85
+ ),
86
+ updated: new Date().toISOString(),
87
+ }))
45
88
  chat.set('nextMessage', '')
89
+ chat.uploadManager.reset()
46
90
  }, [chat])
47
91
 
48
92
  const onKeyDown = useCallback((event: React.KeyboardEvent<HTMLTextAreaElement>) => {
@@ -59,33 +103,34 @@ export const MessageInput = () => {
59
103
  }, [isLoading])
60
104
 
61
105
  return (
62
- <MessageInputBox aria-busy={isLoading} className="message-input" $inputFocused={focused}>
63
- <div className="wrapper-action">
64
- <QuickCommandSelector inputRef={textAreaRef} isTrial={isTrial} />
65
- <AgentSelector inputRef={textAreaRef} isTrial={isTrial} />
66
- <div className={listToClass(['action-box', focused && 'focused', isLoading && 'disabled'])}>
67
- <ButtonAgent />
68
- <AdaptiveTextArea
69
- ref={textAreaRef}
70
- placeholder={agentLabel && interpolate(t.placeholder, agentLabel)}
71
- onChange={e => chat.set('nextMessage', e.target.value)}
72
- value={value}
73
- onFocus={() => setFocused(true)}
74
- onBlur={() => setFocused(false)}
75
- onKeyDown={onKeyDown}
76
- onKeyUp={handleKeyUp}
77
- onIncreaseSize={() => setExpanded(false)}
78
- onResetSize={() => !expansionLocked.current && setExpanded(true)}
79
- maxHeight={isMinimized ? MIN_INPUT_HEIGHT : MAX_INPUT_HEIGHT}
80
- />
106
+ <UploadProvider value={chat.uploadManager}>
107
+ <MessageInputBox aria-busy={isLoading} className="message-input" $inputFocused={focused}>
108
+ <div className="wrapper-action">
109
+ <QuickCommandSelector inputRef={textAreaRef} isTrial={isTrial} />
110
+ <AgentSelector inputRef={textAreaRef} isTrial={isTrial} />
111
+ <div className={listToClass(['action-box', focused && 'focused', isLoading && 'disabled'])}>
112
+ <ButtonAgent />
113
+ <AdaptiveTextArea
114
+ ref={textAreaRef}
115
+ placeholder={agentLabel && interpolate(t.placeholder, agentLabel)}
116
+ onChange={e => chat.set('nextMessage', e.target.value)}
117
+ value={value}
118
+ onFocus={() => setFocused(true)}
119
+ onBlur={() => setFocused(false)}
120
+ onKeyDown={onKeyDown}
121
+ onKeyUp={handleKeyUp}
122
+ onIncreaseSize={() => setExpanded(false)}
123
+ onResetSize={() => !expansionLocked.current && setExpanded(true)}
124
+ maxHeight={isMinimized ? MIN_INPUT_HEIGHT : MAX_INPUT_HEIGHT}
125
+ />
126
+ </div>
81
127
  </div>
82
- </div>
83
- <ProgressBar visible={true} animate={isLoading}
84
- backgroundColor={isLoading || !focused ? theme.color.light[500] : theme.color.primary[500]} />
85
- <InfoBar />
86
- <ButtonBar onSend={onSend} isLoading={isLoading} />
87
- </MessageInputBox>
128
+ <ProgressBar visible={true} animate={isLoading}
129
+ backgroundColor={isLoading || !focused ? theme.color.light[500] : theme.color.primary[500]} />
130
+ <ContextBar />
131
+ <UploadBar />
132
+ <ButtonBar onSend={onSend} isLoading={isLoading} />
133
+ </MessageInputBox>
134
+ </UploadProvider>
88
135
  )
89
136
  }
90
-
91
-
@@ -2,8 +2,10 @@ import { IconButton } from '@citric/ui'
2
2
  import { theme } from '@stack-spot/portal-theme'
3
3
  import { styled } from 'styled-components'
4
4
 
5
- const INFO_BAR_HEIGHT = 38
6
- const INFO_BAR_DISPLACEMENT = 4
5
+ const CONTEXT_BAR_HEIGHT = 38
6
+ const CONTEXT_BAR_DISPLACEMENT = 4
7
+ const UPLOAD_BAR_HEIGHT = 60
8
+ const UPLOAD_BAR_DISPLACEMENT = 4
7
9
  export const MAX_INPUT_HEIGHT = 300
8
10
  export const MIN_INPUT_HEIGHT = 24
9
11
 
@@ -60,7 +62,7 @@ export const MessageInputBox = styled.div<{$inputFocused?: boolean}>`
60
62
 
61
63
  &.visible {
62
64
  > .space {
63
- height: ${INFO_BAR_HEIGHT - INFO_BAR_DISPLACEMENT}px;
65
+ height: var(--space-height, 'auto');
64
66
  }
65
67
  }
66
68
 
@@ -74,17 +76,15 @@ export const MessageInputBox = styled.div<{$inputFocused?: boolean}>`
74
76
  top: 0;
75
77
  left: 0;
76
78
  right: 0;
77
- height: ${INFO_BAR_HEIGHT}px;
79
+ height: var(--content-height, 'auto');
78
80
  padding-top: 8px;
79
81
  background-color: ${theme.color.light[500]};
80
82
  display: flex;
81
83
  flex-direction: row;
82
84
  gap: 4px;
83
- border-right: 2px solid ${({ $inputFocused }) => theme.color.light[$inputFocused ? 600 : 500]};
84
- border-left: 2px solid ${({ $inputFocused }) => theme.color.light[$inputFocused ? 600 : 500]};
85
85
 
86
86
  .list-overflow {
87
- max-width: calc(100% - 30px); // close button + gap
87
+ max-width: calc(100% - var(--list-margins, 0px));
88
88
  height: 24px;
89
89
  &:first-child {
90
90
  margin-left: 0.25rem; // space added to the left when the close all button isn't rendered
@@ -100,31 +100,54 @@ export const MessageInputBox = styled.div<{$inputFocused?: boolean}>`
100
100
  align-items: center;
101
101
  gap: 6px;
102
102
  }
103
+ }
104
+ }
103
105
 
104
- .info-badge > span {
105
- display: flex;
106
- flex-direction: row;
107
- align-items: center;
108
- gap: 4px;
109
- line-height: 0.75rem;
110
- white-space: nowrap;
111
-
112
- ${IconButton} {
113
- padding: 4px 0;
114
- background: none;
115
- border: none;
116
- width: auto;
117
- height: auto;
106
+ > .context-bar {
107
+ --space-height: ${CONTEXT_BAR_HEIGHT - CONTEXT_BAR_DISPLACEMENT}px;
108
+ --content-height: ${CONTEXT_BAR_HEIGHT}px;
109
+ --list-margins: 30px; // close button width + gap
118
110
 
119
- svg {
120
- width: auto;
121
- height: 12px;
122
- }
111
+ .context-badge > span {
112
+ display: flex;
113
+ flex-direction: row;
114
+ align-items: center;
115
+ gap: 4px;
116
+ line-height: 0.75rem;
117
+ white-space: nowrap;
118
+
119
+ ${IconButton} {
120
+ padding: 4px 0;
121
+ background: none;
122
+ border: none;
123
+ width: auto;
124
+ height: auto;
125
+
126
+ svg {
127
+ width: auto;
128
+ height: 12px;
123
129
  }
124
130
  }
125
131
  }
126
132
  }
127
133
 
134
+ > .upload-bar {
135
+ --space-height: ${UPLOAD_BAR_HEIGHT - UPLOAD_BAR_DISPLACEMENT}px;
136
+ --content-height: ${UPLOAD_BAR_HEIGHT}px;
137
+ --list-margins: 12px; // margins from .list-overflow
138
+
139
+ .list-overflow {
140
+ margin: 0 6px !important;
141
+ .scroll-to-left, .scroll-to-right {
142
+ top: 11px;
143
+ }
144
+ }
145
+
146
+ input[type="file"] {
147
+ display: none;
148
+ }
149
+ }
150
+
128
151
  .wrapper-action {
129
152
  position: relative;
130
153
 
@@ -153,8 +176,6 @@ export const MessageInputBox = styled.div<{$inputFocused?: boolean}>`
153
176
  }
154
177
  }
155
178
 
156
-
157
-
158
179
  .button-group {
159
180
  display: flex;
160
181
  flex-direction: row;
@@ -252,6 +273,14 @@ export const MessageInputBox = styled.div<{$inputFocused?: boolean}>`
252
273
  }
253
274
  }
254
275
 
276
+ .message-menu {
277
+ position: absolute;
278
+ bottom: 34px;
279
+ .upload-item {
280
+ border-top: 1px solid ${theme.color.light[600]};
281
+ }
282
+ }
283
+
255
284
  textarea {
256
285
  resize: none;
257
286
  border: none;
@@ -1 +0,0 @@
1
- {"version":3,"file":"InfoBar.d.ts","sourceRoot":"","sources":["../../../src/views/MessageInput/InfoBar.tsx"],"names":[],"mappings":"AA6BA;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,+CA8EnB,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"InfoBar.js","sourceRoot":"","sources":["../../../src/views/MessageInput/InfoBar.tsx"],"names":[],"mappings":"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"}