@stack-spot/ai-chat-widget 2.8.4 → 2.9.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 (71) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/app-metadata.json +3 -3
  3. package/dist/chat-interceptors/quick-commands.js +2 -2
  4. package/dist/chat-interceptors/quick-commands.js.map +1 -1
  5. package/dist/views/Chat/ButtonExecutionDetail.d.ts +5 -0
  6. package/dist/views/Chat/ButtonExecutionDetail.d.ts.map +1 -0
  7. package/dist/views/Chat/ButtonExecutionDetail.js +34 -0
  8. package/dist/views/Chat/ButtonExecutionDetail.js.map +1 -0
  9. package/dist/views/Chat/ChatMessage.d.ts.map +1 -1
  10. package/dist/views/Chat/ChatMessage.js +9 -7
  11. package/dist/views/Chat/ChatMessage.js.map +1 -1
  12. package/dist/views/Steps/FlowChart/HandleGroup.d.ts +4 -1
  13. package/dist/views/Steps/FlowChart/HandleGroup.d.ts.map +1 -1
  14. package/dist/views/Steps/FlowChart/HandleGroup.js +1 -1
  15. package/dist/views/Steps/FlowChart/HandleGroup.js.map +1 -1
  16. package/dist/views/Steps/FlowChart/NodeDynamic.d.ts +15 -0
  17. package/dist/views/Steps/FlowChart/NodeDynamic.d.ts.map +1 -0
  18. package/dist/views/Steps/FlowChart/NodeDynamic.js +41 -0
  19. package/dist/views/Steps/FlowChart/NodeDynamic.js.map +1 -0
  20. package/dist/views/Steps/FlowChart/NodeStep.d.ts +4 -1
  21. package/dist/views/Steps/FlowChart/NodeStep.d.ts.map +1 -1
  22. package/dist/views/Steps/FlowChart/NodeStep.js +2 -2
  23. package/dist/views/Steps/FlowChart/NodeStep.js.map +1 -1
  24. package/dist/views/Steps/FlowChart/hooks.d.ts +7 -0
  25. package/dist/views/Steps/FlowChart/hooks.d.ts.map +1 -0
  26. package/dist/views/Steps/FlowChart/hooks.js +31 -0
  27. package/dist/views/Steps/FlowChart/hooks.js.map +1 -0
  28. package/dist/views/Steps/FlowChart/index.d.ts +4 -2
  29. package/dist/views/Steps/FlowChart/index.d.ts.map +1 -1
  30. package/dist/views/Steps/FlowChart/index.js +53 -23
  31. package/dist/views/Steps/FlowChart/index.js.map +1 -1
  32. package/dist/views/Steps/FlowChart/layout.d.ts +4 -13
  33. package/dist/views/Steps/FlowChart/layout.d.ts.map +1 -1
  34. package/dist/views/Steps/FlowChart/layout.js +25 -7
  35. package/dist/views/Steps/FlowChart/layout.js.map +1 -1
  36. package/dist/views/Steps/FlowChart/styled.d.ts +0 -1
  37. package/dist/views/Steps/FlowChart/styled.d.ts.map +1 -1
  38. package/dist/views/Steps/FlowChart/styled.js +39 -15
  39. package/dist/views/Steps/FlowChart/styled.js.map +1 -1
  40. package/dist/views/Steps/FlowChart/types.d.ts +14 -2
  41. package/dist/views/Steps/FlowChart/types.d.ts.map +1 -1
  42. package/dist/views/Steps/StepModal.d.ts +2 -1
  43. package/dist/views/Steps/StepModal.d.ts.map +1 -1
  44. package/dist/views/Steps/StepModal.js +24 -7
  45. package/dist/views/Steps/StepModal.js.map +1 -1
  46. package/dist/views/Steps/StepsPanel.d.ts.map +1 -1
  47. package/dist/views/Steps/StepsPanel.js +6 -2
  48. package/dist/views/Steps/StepsPanel.js.map +1 -1
  49. package/dist/views/Steps/dictionary.d.ts +5 -1
  50. package/dist/views/Steps/dictionary.d.ts.map +1 -1
  51. package/dist/views/Steps/dictionary.js +4 -0
  52. package/dist/views/Steps/dictionary.js.map +1 -1
  53. package/dist/views/Steps/utils.js +2 -2
  54. package/dist/views/Steps/utils.js.map +1 -1
  55. package/package.json +2 -2
  56. package/src/app-metadata.json +3 -3
  57. package/src/chat-interceptors/quick-commands.ts +2 -2
  58. package/src/views/Chat/ButtonExecutionDetail.tsx +46 -0
  59. package/src/views/Chat/ChatMessage.tsx +10 -6
  60. package/src/views/Steps/FlowChart/HandleGroup.tsx +5 -3
  61. package/src/views/Steps/FlowChart/NodeDynamic.tsx +97 -0
  62. package/src/views/Steps/FlowChart/NodeStep.tsx +6 -4
  63. package/src/views/Steps/FlowChart/hooks.ts +41 -0
  64. package/src/views/Steps/FlowChart/index.tsx +67 -23
  65. package/src/views/Steps/FlowChart/layout.ts +39 -16
  66. package/src/views/Steps/FlowChart/styled.ts +39 -15
  67. package/src/views/Steps/FlowChart/types.ts +16 -2
  68. package/src/views/Steps/StepModal.tsx +36 -13
  69. package/src/views/Steps/StepsPanel.tsx +9 -2
  70. package/src/views/Steps/dictionary.ts +4 -0
  71. package/src/views/Steps/utils.tsx +2 -2
@@ -1,14 +1,28 @@
1
1
  import { ChatStep } from '@stack-spot/portal-network'
2
+ import { Node } from '@xyflow/react'
3
+ import { ChatEntry } from '../../../state/ChatEntry'
4
+
5
+ export type NodeType = 'step' | 'planning' | 'answer' | 'tool'
2
6
 
3
7
  export interface NodeData {
4
8
  nextStatus: ChatStep['status'] | undefined,
5
- onClick?: () => void,
9
+ onClick?: (toolIndex?: number) => void,
6
10
  step: ChatStep,
7
11
  index: number,
12
+ message: ChatEntry,
13
+ onResize?: (size: { width: number, height: number }) => void,
8
14
  }
9
15
 
10
16
  export interface NodeWithoutLayout {
11
17
  id: string,
12
- type: 'step' | 'planning' | 'answer' | 'tool',
18
+ type: NodeType,
13
19
  data?: NodeData,
14
20
  }
21
+
22
+ export type NodeDataFullProps = NodeData & Record<string, unknown>
23
+
24
+ export interface NodeFullProps extends Node<NodeDataFullProps> {
25
+ type: NodeType,
26
+ }
27
+
28
+
@@ -1,5 +1,7 @@
1
- import { Badge, IconButton, Row, Text } from '@stack-spot/citric-react'
1
+ import { Avatar, Badge, Divider, IconButton, Row, Text } from '@stack-spot/citric-react'
2
+ import { ChatAgentTool } from '@stack-spot/portal-network'
2
3
  import { theme } from '@stack-spot/portal-theme'
4
+ import { isNil } from 'lodash'
3
5
  import { useMemo, useState } from 'react'
4
6
  import { styled } from 'styled-components'
5
7
  import { Code } from '../../components/Code'
@@ -14,6 +16,7 @@ import { getTitle, toPrecision } from './utils'
14
16
  interface Props {
15
17
  message: ChatEntry,
16
18
  stepId: string | undefined,
19
+ toolIndex?: number,
17
20
  onClose: () => void,
18
21
  }
19
22
 
@@ -43,16 +46,26 @@ const StyledSection = styled.section`
43
46
  align-items: start;
44
47
  align-self: stretch;
45
48
  gap: 6px;
46
- background-color: ${theme.color.light[500]};
49
+ background-color: ${theme.color.light[400]};
47
50
  border-radius: 5px;
48
- padding: 6px;
51
+ padding: 0 6px;
49
52
 
50
53
  &:not(:last-child) {
51
54
  border-bottom: 1px solid ${theme.color.light[500]};
52
55
  }
53
56
 
57
+ hr {
58
+ margin: 16px 0;
59
+ }
60
+
61
+ .header-code {
62
+ background-color: ${theme.color.light[300]};
63
+ }
64
+
54
65
  .tool-input {
55
66
  align-self: stretch;
67
+ border: 1px solid ${theme.color.light[600]};
68
+ margin-top: 8px;
56
69
  &, .highlighter {
57
70
  background: ${theme.color.light[300]} !important;
58
71
  }
@@ -118,29 +131,39 @@ const ExecutionBox = styled.div`
118
131
  }
119
132
  `
120
133
 
121
- export const StepModal = ({ message, stepId, onClose }: Props) => {
134
+ export const StepModal = ({ message, stepId, toolIndex, onClose }: Props) => {
122
135
  const t = useStepsDictionary()
123
136
  const entry = useChatEntry(message)
124
137
  const [attempt, setAttempt] = useState(0)
125
138
  const stepIndex = useMemo(() => entry.steps?.findIndex(s => s.id === stepId) ?? -1, [entry, stepId])
126
139
  const step = entry.steps?.[stepIndex]
140
+ const showSingleTool = !isNil(toolIndex)
141
+ const attemptTools: ChatAgentTool[] | undefined = step?.type === 'step' ? step.attempts[attempt]?.tools : undefined
142
+ const toolsToRender = showSingleTool && attemptTools ? [attemptTools[toolIndex]].filter(Boolean) : attemptTools
127
143
 
128
- const tools = step?.type === 'step' ? step.attempts[attempt]?.tools?.map(tool => (
144
+ const tools = toolsToRender?.map(tool => (
129
145
  <div className="tool" key={tool.id}>
130
- <ToolBadge name={tool.name ?? ''} duration={tool.duration} image={tool.image} description={tool.description} />
146
+ {!showSingleTool && <ToolBadge name={tool.name ?? ''} duration={tool.duration} image={tool.image} description={tool.description} />}
131
147
  {tool.input && <>
132
- <Text appearance="microtext1" color="light.700">{t.input}:</Text>
148
+ <Badge appearance="square" colorPalette="cyan">{t.input}</Badge>
133
149
  <Code language="json" className="tool-input" showLineNumbers={false} showActionBar>{tool.input}</Code>
134
150
  </>}
135
151
  {tool.output && <>
136
- <Text appearance="microtext1" color="light.700">{t.response}:</Text>
152
+ <Divider />
153
+ <Badge appearance="square" colorPalette="cyan">{t.response}</Badge>
137
154
  <Code language="json" className="tool-input" showLineNumbers={false} showActionBar>{tool.output}</Code>
138
155
  </>}
139
156
  </div>
140
- )) : undefined
157
+ ))
141
158
 
142
- const title = (
143
- <Row flex={1} justifyContent="space-between">
159
+ const singleTool = showSingleTool ? toolsToRender?.[0] : undefined
160
+
161
+ const title = (showSingleTool
162
+ ? <Row flex={1} gap="8px">
163
+ {!!singleTool?.name && <Avatar size="xxs" image={singleTool?.image} name={singleTool?.name} />}
164
+ <Text appearance="h6">{singleTool?.name ?? t.finalAnswer}</Text>
165
+ </Row>
166
+ : <Row flex={1} justifyContent="space-between">
144
167
  <Text appearance="h6">{getTitle(t, step, stepIndex)}</Text>
145
168
  <ExecutionBox>
146
169
  <Text className="time" appearance="microtext1">
@@ -176,7 +199,7 @@ export const StepModal = ({ message, stepId, onClose }: Props) => {
176
199
  return (
177
200
  <Modal open={!!step} onClose={onClose} title={title}>
178
201
  {step?.type === 'answer' && <StyledSection className="restrict-image-size">
179
- {entry.type === 'md' ? <Markdown>{entry.content}</Markdown> : <Text>{entry.content}</Text>}
202
+ {entry.type === 'md' ? <Markdown>{entry.content}</Markdown> : <Text>{entry.content}</Text>}
180
203
  </StyledSection>}
181
204
 
182
205
  {step?.type === 'planning' && <StyledSection style={{ alignItems: 'stretch' }}>
@@ -199,7 +222,7 @@ export const StepModal = ({ message, stepId, onClose }: Props) => {
199
222
  ))}
200
223
  </ul>
201
224
  </StyledSection>}
202
-
225
+
203
226
  {step?.type === 'step' && step?.input && <StyledSection>
204
227
  <Badge appearance="square" colorPalette="blue">Prompt</Badge>
205
228
  <Text>{step.input}</Text>
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable import/no-default-export */
2
2
 
3
+ import { ChatStep } from '@stack-spot/portal-network'
3
4
  import { useMemo, useState } from 'react'
4
5
  import { useWidget } from '../../context/hooks'
5
6
  import { FlowChart } from './FlowChart'
@@ -7,16 +8,22 @@ import { StepModal } from './StepModal'
7
8
 
8
9
  const StepsPanel = ({ chatId, messageId }: { chatId: string, messageId: number }) => {
9
10
  const [currentStepId, setCurrentStepId] = useState<string | undefined>()
11
+ const [toolIndex, setToolIndex] = useState<number | undefined>()
10
12
  const widget = useWidget()
11
13
  const message = useMemo(
12
14
  () => widget.chatTabs.getAll().find(c => c.id === chatId)?.getMessages().find(m => m.id === messageId),
13
15
  [chatId, messageId],
14
16
  )
15
17
 
18
+ const handleClick = (step: ChatStep, tooIndex?: number) => {
19
+ setCurrentStepId(step.id)
20
+ setToolIndex(tooIndex)
21
+ }
22
+
16
23
  return message ? (
17
24
  <>
18
- <FlowChart message={message} onClick={(step) => setCurrentStepId(step.id)} />
19
- <StepModal message={message} stepId={currentStepId} onClose={() => setCurrentStepId(undefined)} />
25
+ <FlowChart message={message} onClick={handleClick} direction="TB" />
26
+ <StepModal message={message} stepId={currentStepId} toolIndex={toolIndex} onClose={() => setCurrentStepId(undefined)} />
20
27
  </>
21
28
  ) : null
22
29
  }
@@ -18,6 +18,8 @@ export const dictionary = {
18
18
  open: 'Open',
19
19
  close: 'Close',
20
20
  input: 'Input',
21
+ finalAnswer: 'Final answer',
22
+ userPrompt: 'User prompt',
21
23
  },
22
24
  pt: {
23
25
  stepsPanelDescription: 'Os passos e ferramentas usados para chegar na resposta',
@@ -34,6 +36,8 @@ export const dictionary = {
34
36
  nextAttempt: 'Próxima execução',
35
37
  previousAttempt: 'Execução anterior',
36
38
  input: 'Entrada',
39
+ finalAnswer: 'Resposta final',
40
+ userPrompt: 'Prompt do usuário',
37
41
  },
38
42
  } satisfies Dictionary
39
43
 
@@ -14,8 +14,8 @@ export function getStatusIcon(status: ChatStep['status']) {
14
14
 
15
15
  export function getTypeIcon(type: ChatStep['type']): WithIcon {
16
16
  switch (type) {
17
- case 'planning': return { group: 'outline', icon: 'ListUnordered' }
18
- default: return { group: 'fill', icon: 'Play' }
17
+ case 'planning': return { group: 'fill', icon: 'ChevronRight' }
18
+ default: return { group: 'outline', icon: 'StackSpot' }
19
19
  }
20
20
  }
21
21