agent-log-item.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import {
  2. useMemo,
  3. useState,
  4. } from 'react'
  5. import {
  6. RiArrowRightSLine,
  7. RiListView,
  8. } from '@remixicon/react'
  9. import cn from '@/utils/classnames'
  10. import Button from '@/app/components/base/button'
  11. import type { AgentLogItemWithChildren } from '@/types/workflow'
  12. import NodeStatusIcon from '@/app/components/workflow/nodes/_base/components/node-status-icon'
  13. import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor'
  14. import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
  15. import BlockIcon from '@/app/components/workflow/block-icon'
  16. import { BlockEnum } from '@/app/components/workflow/types'
  17. import useGetIcon from '@/app/components/plugins/install-plugin/base/use-get-icon'
  18. type AgentLogItemProps = {
  19. item: AgentLogItemWithChildren
  20. onShowAgentOrToolLog: (detail: AgentLogItemWithChildren) => void
  21. }
  22. const AgentLogItem = ({
  23. item,
  24. onShowAgentOrToolLog,
  25. }: AgentLogItemProps) => {
  26. const {
  27. label,
  28. status,
  29. children,
  30. data,
  31. metadata,
  32. } = item
  33. const [expanded, setExpanded] = useState(false)
  34. const { getIconUrl } = useGetIcon()
  35. const toolIcon = useMemo(() => {
  36. const icon = metadata?.icon
  37. if (icon) {
  38. if (icon.includes('http'))
  39. return icon
  40. return getIconUrl(icon)
  41. }
  42. return ''
  43. }, [getIconUrl, metadata?.icon])
  44. const mergeStatus = useMemo(() => {
  45. if (status === 'start')
  46. return 'running'
  47. return status
  48. }, [status])
  49. return (
  50. <div className='bg-background-default border-[0.5px] border-components-panel-border rounded-[10px]'>
  51. <div
  52. className={cn(
  53. 'flex items-center pl-1.5 pt-2 pr-3 pb-2 cursor-pointer',
  54. expanded && 'pb-1',
  55. )}
  56. onClick={() => setExpanded(!expanded)}
  57. >
  58. {
  59. expanded
  60. ? <RiArrowRightSLine className='shrink-0 w-4 h-4 rotate-90 text-text-quaternary' />
  61. : <RiArrowRightSLine className='shrink-0 w-4 h-4 text-text-quaternary' />
  62. }
  63. <BlockIcon
  64. className='shrink-0 mr-1.5'
  65. type={toolIcon ? BlockEnum.Tool : BlockEnum.Agent}
  66. toolIcon={toolIcon}
  67. />
  68. <div
  69. className='grow system-sm-semibold-uppercase text-text-secondary truncate'
  70. title={label}
  71. >
  72. {label}
  73. </div>
  74. {
  75. metadata?.elapsed_time && (
  76. <div className='shrink-0 mr-2 system-xs-regular text-text-tertiary'>{metadata?.elapsed_time?.toFixed(3)}s</div>
  77. )
  78. }
  79. <NodeStatusIcon status={mergeStatus} />
  80. </div>
  81. {
  82. expanded && (
  83. <div className='p-1 pt-0'>
  84. {
  85. !!children?.length && (
  86. <Button
  87. className='flex items-center justify-between mb-1 w-full'
  88. variant='tertiary'
  89. onClick={() => onShowAgentOrToolLog(item)}
  90. >
  91. <div className='flex items-center'>
  92. <RiListView className='mr-1 w-4 h-4 text-components-button-tertiary-text shrink-0' />
  93. {`${children.length} Action Logs`}
  94. </div>
  95. <div className='flex'>
  96. <RiArrowRightSLine className='w-4 h-4 text-components-button-tertiary-text shrink-0' />
  97. </div>
  98. </Button>
  99. )
  100. }
  101. {
  102. data && (
  103. <CodeEditor
  104. readOnly
  105. title={<div>{'data'.toLocaleUpperCase()}</div>}
  106. language={CodeLanguage.json}
  107. value={data}
  108. isJSONStringifyBeauty
  109. />
  110. )
  111. }
  112. </div>
  113. )
  114. }
  115. </div>
  116. )
  117. }
  118. export default AgentLogItem