@devicai/ui 0.57.0 → 0.58.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 (171) hide show
  1. package/README.md +162 -0
  2. package/dist/cjs/api/types.js.map +1 -1
  3. package/dist/cjs/components/AICommandBar/AICommandBar.js +10 -7
  4. package/dist/cjs/components/AICommandBar/AICommandBar.js.map +1 -1
  5. package/dist/cjs/components/AICommandBar/useAICommandBar.js +7 -5
  6. package/dist/cjs/components/AICommandBar/useAICommandBar.js.map +1 -1
  7. package/dist/cjs/components/AIElementWrapper/AIElementWrapper.js +17 -14
  8. package/dist/cjs/components/AIElementWrapper/AIElementWrapper.js.map +1 -1
  9. package/dist/cjs/components/AIElementWrapper/useAIElementWrapper.js +7 -5
  10. package/dist/cjs/components/AIElementWrapper/useAIElementWrapper.js.map +1 -1
  11. package/dist/cjs/components/AIGenerationButton/AIGenerationButton.js +11 -6
  12. package/dist/cjs/components/AIGenerationButton/AIGenerationButton.js.map +1 -1
  13. package/dist/cjs/components/AIGenerationButton/useAIGenerationButton.js +6 -4
  14. package/dist/cjs/components/AIGenerationButton/useAIGenerationButton.js.map +1 -1
  15. package/dist/cjs/components/ChatDrawer/ChatDrawer.js +26 -12
  16. package/dist/cjs/components/ChatDrawer/ChatDrawer.js.map +1 -1
  17. package/dist/cjs/components/ChatDrawer/ChatInput.js +21 -15
  18. package/dist/cjs/components/ChatDrawer/ChatInput.js.map +1 -1
  19. package/dist/cjs/components/ChatDrawer/ChatMessages.js +54 -13
  20. package/dist/cjs/components/ChatDrawer/ChatMessages.js.map +1 -1
  21. package/dist/cjs/components/ChatDrawer/CompactionWidget.js +13 -4
  22. package/dist/cjs/components/ChatDrawer/CompactionWidget.js.map +1 -1
  23. package/dist/cjs/components/ChatDrawer/ConversationSelector.js +6 -4
  24. package/dist/cjs/components/ChatDrawer/ConversationSelector.js.map +1 -1
  25. package/dist/cjs/components/ChatDrawer/GuardrailNotice.js +40 -0
  26. package/dist/cjs/components/ChatDrawer/GuardrailNotice.js.map +1 -0
  27. package/dist/cjs/components/ChatDrawer/HandoffSubagentWidget.js +3 -1
  28. package/dist/cjs/components/ChatDrawer/HandoffSubagentWidget.js.map +1 -1
  29. package/dist/cjs/components/ChatDrawer/LimitBanner.js +19 -9
  30. package/dist/cjs/components/ChatDrawer/LimitBanner.js.map +1 -1
  31. package/dist/cjs/components/ChatDrawer/QueueNotice.js +19 -7
  32. package/dist/cjs/components/ChatDrawer/QueueNotice.js.map +1 -1
  33. package/dist/cjs/components/ChatDrawer/RecalledMemoriesWidget.js +17 -5
  34. package/dist/cjs/components/ChatDrawer/RecalledMemoriesWidget.js.map +1 -1
  35. package/dist/cjs/components/ChatDrawer/ReferenceChip.js +3 -1
  36. package/dist/cjs/components/ChatDrawer/ReferenceChip.js.map +1 -1
  37. package/dist/cjs/components/ChatDrawer/UsageBar.js +23 -18
  38. package/dist/cjs/components/ChatDrawer/UsageBar.js.map +1 -1
  39. package/dist/cjs/components/CoreMemoryModal/CoreMemoryModal.js +20 -9
  40. package/dist/cjs/components/CoreMemoryModal/CoreMemoryModal.js.map +1 -1
  41. package/dist/cjs/components/Feedback/FeedbackModal.js +5 -1
  42. package/dist/cjs/components/Feedback/FeedbackModal.js.map +1 -1
  43. package/dist/cjs/components/Feedback/MessageActions.js +3 -1
  44. package/dist/cjs/components/Feedback/MessageActions.js.map +1 -1
  45. package/dist/cjs/components/IntegrationsModal/ConnectFieldsForm.js +12 -8
  46. package/dist/cjs/components/IntegrationsModal/ConnectFieldsForm.js.map +1 -1
  47. package/dist/cjs/components/IntegrationsModal/IntegrationsHint.js +5 -3
  48. package/dist/cjs/components/IntegrationsModal/IntegrationsHint.js.map +1 -1
  49. package/dist/cjs/components/IntegrationsModal/IntegrationsLauncher.js +12 -3
  50. package/dist/cjs/components/IntegrationsModal/IntegrationsLauncher.js.map +1 -1
  51. package/dist/cjs/components/IntegrationsModal/IntegrationsPanel.js +34 -24
  52. package/dist/cjs/components/IntegrationsModal/IntegrationsPanel.js.map +1 -1
  53. package/dist/cjs/components/IntegrationsModal/IntegrationsToggle.js +15 -6
  54. package/dist/cjs/components/IntegrationsModal/IntegrationsToggle.js.map +1 -1
  55. package/dist/cjs/components/IntegrationsModal/McpConnectForm.js +15 -7
  56. package/dist/cjs/components/IntegrationsModal/McpConnectForm.js.map +1 -1
  57. package/dist/cjs/components/IntegrationsModal/McpServersSection.js +32 -19
  58. package/dist/cjs/components/IntegrationsModal/McpServersSection.js.map +1 -1
  59. package/dist/cjs/components/IntegrationsModal/useIntegrations.js +3 -1
  60. package/dist/cjs/components/IntegrationsModal/useIntegrations.js.map +1 -1
  61. package/dist/cjs/components/IntegrationsModal/useTenantMcp.js +3 -1
  62. package/dist/cjs/components/IntegrationsModal/useTenantMcp.js.map +1 -1
  63. package/dist/cjs/components/ThreadStateTag/ThreadStateTag.js +63 -40
  64. package/dist/cjs/components/ThreadStateTag/ThreadStateTag.js.map +1 -1
  65. package/dist/cjs/hooks/useDevicChat.js +11 -5
  66. package/dist/cjs/hooks/useDevicChat.js.map +1 -1
  67. package/dist/cjs/hooks/useSpeechRecording.js +8 -4
  68. package/dist/cjs/hooks/useSpeechRecording.js.map +1 -1
  69. package/dist/cjs/i18n/translate.js +48 -0
  70. package/dist/cjs/i18n/translate.js.map +1 -0
  71. package/dist/cjs/i18n/useTranslations.js +57 -0
  72. package/dist/cjs/i18n/useTranslations.js.map +1 -0
  73. package/dist/cjs/index.js +11 -0
  74. package/dist/cjs/index.js.map +1 -1
  75. package/dist/cjs/provider/DevicProvider.js +3 -1
  76. package/dist/cjs/provider/DevicProvider.js.map +1 -1
  77. package/dist/cjs/styles.css +1 -1
  78. package/dist/esm/api/types.d.ts +10 -1
  79. package/dist/esm/api/types.js.map +1 -1
  80. package/dist/esm/components/AICommandBar/AICommandBar.js +11 -8
  81. package/dist/esm/components/AICommandBar/AICommandBar.js.map +1 -1
  82. package/dist/esm/components/AICommandBar/AICommandBar.types.d.ts +10 -0
  83. package/dist/esm/components/AICommandBar/useAICommandBar.js +7 -5
  84. package/dist/esm/components/AICommandBar/useAICommandBar.js.map +1 -1
  85. package/dist/esm/components/AIElementWrapper/AIElementWrapper.js +17 -14
  86. package/dist/esm/components/AIElementWrapper/AIElementWrapper.js.map +1 -1
  87. package/dist/esm/components/AIElementWrapper/AIElementWrapper.types.d.ts +10 -0
  88. package/dist/esm/components/AIElementWrapper/useAIElementWrapper.js +7 -5
  89. package/dist/esm/components/AIElementWrapper/useAIElementWrapper.js.map +1 -1
  90. package/dist/esm/components/AIGenerationButton/AIGenerationButton.js +12 -7
  91. package/dist/esm/components/AIGenerationButton/AIGenerationButton.js.map +1 -1
  92. package/dist/esm/components/AIGenerationButton/AIGenerationButton.types.d.ts +10 -0
  93. package/dist/esm/components/AIGenerationButton/useAIGenerationButton.js +6 -4
  94. package/dist/esm/components/AIGenerationButton/useAIGenerationButton.js.map +1 -1
  95. package/dist/esm/components/ChatDrawer/ChatDrawer.js +27 -13
  96. package/dist/esm/components/ChatDrawer/ChatDrawer.js.map +1 -1
  97. package/dist/esm/components/ChatDrawer/ChatDrawer.types.d.ts +33 -0
  98. package/dist/esm/components/ChatDrawer/ChatInput.js +21 -15
  99. package/dist/esm/components/ChatDrawer/ChatInput.js.map +1 -1
  100. package/dist/esm/components/ChatDrawer/ChatMessages.d.ts +1 -1
  101. package/dist/esm/components/ChatDrawer/ChatMessages.js +54 -13
  102. package/dist/esm/components/ChatDrawer/ChatMessages.js.map +1 -1
  103. package/dist/esm/components/ChatDrawer/CompactionWidget.js +13 -4
  104. package/dist/esm/components/ChatDrawer/CompactionWidget.js.map +1 -1
  105. package/dist/esm/components/ChatDrawer/ConversationSelector.js +6 -4
  106. package/dist/esm/components/ChatDrawer/ConversationSelector.js.map +1 -1
  107. package/dist/esm/components/ChatDrawer/GuardrailNotice.d.ts +36 -0
  108. package/dist/esm/components/ChatDrawer/GuardrailNotice.js +38 -0
  109. package/dist/esm/components/ChatDrawer/GuardrailNotice.js.map +1 -0
  110. package/dist/esm/components/ChatDrawer/HandoffSubagentWidget.js +3 -1
  111. package/dist/esm/components/ChatDrawer/HandoffSubagentWidget.js.map +1 -1
  112. package/dist/esm/components/ChatDrawer/LimitBanner.js +19 -9
  113. package/dist/esm/components/ChatDrawer/LimitBanner.js.map +1 -1
  114. package/dist/esm/components/ChatDrawer/QueueNotice.js +19 -7
  115. package/dist/esm/components/ChatDrawer/QueueNotice.js.map +1 -1
  116. package/dist/esm/components/ChatDrawer/RecalledMemoriesWidget.js +17 -5
  117. package/dist/esm/components/ChatDrawer/RecalledMemoriesWidget.js.map +1 -1
  118. package/dist/esm/components/ChatDrawer/ReferenceChip.js +3 -1
  119. package/dist/esm/components/ChatDrawer/ReferenceChip.js.map +1 -1
  120. package/dist/esm/components/ChatDrawer/UsageBar.js +23 -18
  121. package/dist/esm/components/ChatDrawer/UsageBar.js.map +1 -1
  122. package/dist/esm/components/ChatDrawer/index.d.ts +2 -0
  123. package/dist/esm/components/CoreMemoryModal/CoreMemoryModal.js +20 -9
  124. package/dist/esm/components/CoreMemoryModal/CoreMemoryModal.js.map +1 -1
  125. package/dist/esm/components/Feedback/FeedbackModal.js +5 -1
  126. package/dist/esm/components/Feedback/FeedbackModal.js.map +1 -1
  127. package/dist/esm/components/Feedback/MessageActions.js +3 -1
  128. package/dist/esm/components/Feedback/MessageActions.js.map +1 -1
  129. package/dist/esm/components/IntegrationsModal/ConnectFieldsForm.js +12 -8
  130. package/dist/esm/components/IntegrationsModal/ConnectFieldsForm.js.map +1 -1
  131. package/dist/esm/components/IntegrationsModal/IntegrationsHint.js +5 -3
  132. package/dist/esm/components/IntegrationsModal/IntegrationsHint.js.map +1 -1
  133. package/dist/esm/components/IntegrationsModal/IntegrationsLauncher.js +12 -3
  134. package/dist/esm/components/IntegrationsModal/IntegrationsLauncher.js.map +1 -1
  135. package/dist/esm/components/IntegrationsModal/IntegrationsPanel.d.ts +1 -1
  136. package/dist/esm/components/IntegrationsModal/IntegrationsPanel.js +34 -24
  137. package/dist/esm/components/IntegrationsModal/IntegrationsPanel.js.map +1 -1
  138. package/dist/esm/components/IntegrationsModal/IntegrationsToggle.d.ts +1 -1
  139. package/dist/esm/components/IntegrationsModal/IntegrationsToggle.js +15 -6
  140. package/dist/esm/components/IntegrationsModal/IntegrationsToggle.js.map +1 -1
  141. package/dist/esm/components/IntegrationsModal/McpConnectForm.js +15 -7
  142. package/dist/esm/components/IntegrationsModal/McpConnectForm.js.map +1 -1
  143. package/dist/esm/components/IntegrationsModal/McpServersSection.js +32 -19
  144. package/dist/esm/components/IntegrationsModal/McpServersSection.js.map +1 -1
  145. package/dist/esm/components/IntegrationsModal/useIntegrations.js +3 -1
  146. package/dist/esm/components/IntegrationsModal/useIntegrations.js.map +1 -1
  147. package/dist/esm/components/IntegrationsModal/useTenantMcp.js +3 -1
  148. package/dist/esm/components/IntegrationsModal/useTenantMcp.js.map +1 -1
  149. package/dist/esm/components/ThreadStateTag/ThreadStateTag.js +63 -40
  150. package/dist/esm/components/ThreadStateTag/ThreadStateTag.js.map +1 -1
  151. package/dist/esm/hooks/useDevicChat.js +12 -6
  152. package/dist/esm/hooks/useDevicChat.js.map +1 -1
  153. package/dist/esm/hooks/useSpeechRecording.js +8 -4
  154. package/dist/esm/hooks/useSpeechRecording.js.map +1 -1
  155. package/dist/esm/i18n/index.d.ts +4 -0
  156. package/dist/esm/i18n/translate.d.ts +23 -0
  157. package/dist/esm/i18n/translate.js +43 -0
  158. package/dist/esm/i18n/translate.js.map +1 -0
  159. package/dist/esm/i18n/types.d.ts +27 -0
  160. package/dist/esm/i18n/useTranslations.d.ts +32 -0
  161. package/dist/esm/i18n/useTranslations.js +53 -0
  162. package/dist/esm/i18n/useTranslations.js.map +1 -0
  163. package/dist/esm/index.d.ts +4 -2
  164. package/dist/esm/index.js +3 -0
  165. package/dist/esm/index.js.map +1 -1
  166. package/dist/esm/provider/DevicProvider.d.ts +1 -1
  167. package/dist/esm/provider/DevicProvider.js +3 -1
  168. package/dist/esm/provider/DevicProvider.js.map +1 -1
  169. package/dist/esm/provider/types.d.ts +33 -0
  170. package/dist/esm/styles.css +1 -1
  171. package/package.json +1 -1
@@ -4,61 +4,70 @@ import { createPortal } from 'react-dom';
4
4
  import { useOptionalDevicContext } from '../../provider/DevicContext.js';
5
5
  import { DevicApiClient } from '../../api/client.js';
6
6
  import { AgentThreadState } from '../../api/types.js';
7
+ import { useTranslations } from '../../i18n/useTranslations.js';
7
8
 
8
9
  /* ── State configuration map ── */
9
- function getStateConfig(state, subthreadCount) {
10
+ function getStateConfig(t, state, subthreadCount) {
10
11
  const configs = {
11
12
  [AgentThreadState.QUEUED]: {
12
13
  color: 'gold', bgColor: '#fffbe6', borderColor: '#ffe58f',
13
- text: 'Queued', iconType: null,
14
+ text: t('Queued'), iconType: null,
14
15
  },
15
16
  [AgentThreadState.PROCESSING]: {
16
17
  color: 'processing', bgColor: '#e6f4ff', borderColor: '#91caff',
17
- text: 'Processing', iconType: 'spinner',
18
+ text: t('Processing'), iconType: 'spinner',
18
19
  },
19
20
  [AgentThreadState.COMPLETED]: {
20
21
  color: 'success', bgColor: '#f6ffed', borderColor: '#b7eb8f',
21
- text: 'Completed', iconType: null,
22
+ text: t('Completed'), iconType: null,
22
23
  },
23
24
  [AgentThreadState.FAILED]: {
24
25
  color: 'error', bgColor: '#fff2f0', borderColor: '#ffa39e',
25
- text: 'Failed', iconType: null,
26
+ text: t('Failed'), iconType: null,
26
27
  },
27
28
  [AgentThreadState.TERMINATED]: {
28
29
  color: 'default', bgColor: '#fafafa', borderColor: '#d9d9d9',
29
- text: 'Terminated', iconType: null,
30
+ text: t('Terminated'), iconType: null,
30
31
  },
31
32
  [AgentThreadState.GUARDRAIL_TRIGGER]: {
32
33
  color: 'error', bgColor: '#fff2f0', borderColor: '#ffa39e',
33
- text: 'Guardrail Triggered', iconType: 'shield',
34
+ text: t('Guardrail Triggered'), iconType: 'shield',
34
35
  },
35
36
  [AgentThreadState.PAUSED]: {
36
37
  color: 'purple', bgColor: '#f9f0ff', borderColor: '#d3adf7',
37
- text: 'Paused', iconType: 'pause',
38
+ text: t('Paused'), iconType: 'pause',
38
39
  },
39
40
  [AgentThreadState.PAUSED_FOR_APPROVAL]: {
40
41
  color: 'gold', bgColor: '#fffbe6', borderColor: '#ffe58f',
41
- text: 'Waiting for approval', iconType: 'warning',
42
+ text: t('Waiting for approval'), iconType: 'warning',
42
43
  },
43
44
  [AgentThreadState.APPROVAL_REJECTED]: {
44
45
  color: 'error', bgColor: '#fff2f0', borderColor: '#ffa39e',
45
- text: 'Approval rejected', iconType: null,
46
+ text: t('Approval rejected'), iconType: null,
46
47
  },
47
48
  [AgentThreadState.WAITING_FOR_RESPONSE]: {
48
49
  color: 'gold', bgColor: '#fffbe6', borderColor: '#ffe58f',
49
- text: 'Waiting for response', iconType: 'envelope',
50
+ text: t('Waiting for response'), iconType: 'envelope',
50
51
  },
51
52
  [AgentThreadState.PAUSED_FOR_RESUME]: {
52
53
  color: 'blue', bgColor: '#e6f4ff', borderColor: '#91caff',
53
- text: 'Resume scheduled', iconType: 'clock',
54
+ text: t('Resume scheduled'), iconType: 'clock',
54
55
  },
55
56
  [AgentThreadState.HANDED_OFF]: {
56
57
  color: 'blue', bgColor: '#e6f4ff', borderColor: '#91caff',
57
- text: subthreadCount && subthreadCount > 1 ? `Handed off (${subthreadCount})` : 'Handed off',
58
+ text: subthreadCount && subthreadCount > 1
59
+ ? t('Handed off ({count})', { count: subthreadCount })
60
+ : t('Handed off'),
58
61
  iconType: 'handoff',
59
62
  },
60
63
  };
61
- return configs[state] || { color: 'default', bgColor: '#fafafa', borderColor: '#d9d9d9', text: 'Unknown', iconType: null };
64
+ return (configs[state] || {
65
+ color: 'default',
66
+ bgColor: '#fafafa',
67
+ borderColor: '#d9d9d9',
68
+ text: t('Unknown'),
69
+ iconType: null,
70
+ });
62
71
  }
63
72
  /* ── SVG Icons ── */
64
73
  function SpinnerIcon() {
@@ -127,6 +136,7 @@ function Modal({ open, onClose, title, titleIcon, children, footer, }) {
127
136
  }
128
137
  /* ── Explain Modal with typing effect ── */
129
138
  function ExplainModal({ open, onClose, explanation, isLoading, agentName, }) {
139
+ const t = useTranslations();
130
140
  const [displayedText, setDisplayedText] = useState('');
131
141
  const [fullTextDisplayed, setFullTextDisplayed] = useState(false);
132
142
  const charIndexRef = useRef(0);
@@ -154,28 +164,33 @@ function ExplainModal({ open, onClose, explanation, isLoading, agentName, }) {
154
164
  setFullTextDisplayed(false);
155
165
  onClose();
156
166
  };
157
- return (jsx(Modal, { open: open, onClose: handleClose, title: `Thread execution description of "${agentName}"`, titleIcon: jsx(LightbulbIcon, {}), children: isLoading ? (jsx("div", { className: "devic-state-loading", children: jsx("div", { className: "devic-state-loading-spinner" }) })) : (jsxs("div", { className: "devic-explain-content", children: [displayedText, !fullTextDisplayed && jsx("span", { className: "devic-typing-cursor", children: "|" })] })) }));
167
+ return (jsx(Modal, { open: open, onClose: handleClose, title: t('Thread execution description of "{agent}"', {
168
+ agent: agentName,
169
+ }), titleIcon: jsx(LightbulbIcon, {}), children: isLoading ? (jsx("div", { className: "devic-state-loading", children: jsx("div", { className: "devic-state-loading-spinner" }) })) : (jsxs("div", { className: "devic-explain-content", children: [displayedText, !fullTextDisplayed && jsx("span", { className: "devic-typing-cursor", children: "|" })] })) }));
158
170
  }
159
171
  /* ── Approval Modal ── */
160
172
  function ApprovalModal({ open, onClose, onApprove, isLoading, pausedReason, }) {
173
+ const t = useTranslations();
161
174
  const [feedback, setFeedback] = useState('');
162
175
  const handleClose = () => {
163
176
  setFeedback('');
164
177
  onClose();
165
178
  };
166
- return (jsx(Modal, { open: open, onClose: handleClose, title: "Review Agent Request", titleIcon: jsx(EyeIcon, {}), children: jsxs("div", { className: "devic-approval-layout", children: [jsxs("div", { className: "devic-approval-request", children: [jsx("div", { style: { fontWeight: 600, marginBottom: 8, fontSize: 13 }, children: "Agent's request:" }), jsx("div", { style: { whiteSpace: 'pre-wrap' }, children: pausedReason || 'Agent is waiting for approval to resume execution.' })] }), jsxs("div", { className: "devic-approval-actions", children: [jsx("div", { style: { fontWeight: 600, fontSize: 13 }, children: "Your feedback:" }), jsx("textarea", { className: "devic-approval-textarea", value: feedback, onChange: (e) => setFeedback(e.target.value), placeholder: "Optional feedback for the agent..." }), jsxs("div", { className: "devic-approval-buttons", children: [jsx("button", { className: "devic-state-btn devic-state-btn-danger", onClick: () => onApprove('rejected', false, feedback), disabled: isLoading, type: "button", children: "Reject and finish" }), jsx("button", { className: "devic-state-btn devic-state-btn-primary", onClick: () => onApprove('rejected', true, feedback), disabled: isLoading || !feedback.trim(), type: "button", children: "Continue with feedback" }), jsx("button", { className: "devic-state-btn devic-state-btn-success", onClick: () => onApprove('approved', false), disabled: isLoading, type: "button", children: "Approve" })] })] })] }) }));
179
+ return (jsx(Modal, { open: open, onClose: handleClose, title: t('Review Agent Request'), titleIcon: jsx(EyeIcon, {}), children: jsxs("div", { className: "devic-approval-layout", children: [jsxs("div", { className: "devic-approval-request", children: [jsx("div", { style: { fontWeight: 600, marginBottom: 8, fontSize: 13 }, children: t("Agent's request:") }), jsx("div", { style: { whiteSpace: 'pre-wrap' }, children: pausedReason ||
180
+ t('Agent is waiting for approval to resume execution.') })] }), jsxs("div", { className: "devic-approval-actions", children: [jsx("div", { style: { fontWeight: 600, fontSize: 13 }, children: t('Your feedback:') }), jsx("textarea", { className: "devic-approval-textarea", value: feedback, onChange: (e) => setFeedback(e.target.value), placeholder: t('Optional feedback for the agent...') }), jsxs("div", { className: "devic-approval-buttons", children: [jsx("button", { className: "devic-state-btn devic-state-btn-danger", onClick: () => onApprove('rejected', false, feedback), disabled: isLoading, type: "button", children: t('Reject and finish') }), jsx("button", { className: "devic-state-btn devic-state-btn-primary", onClick: () => onApprove('rejected', true, feedback), disabled: isLoading || !feedback.trim(), type: "button", children: t('Continue with feedback') }), jsx("button", { className: "devic-state-btn devic-state-btn-success", onClick: () => onApprove('approved', false), disabled: isLoading, type: "button", children: t('Approve') })] })] })] }) }));
167
181
  }
168
182
  /* ── Send Message Modal ── */
169
183
  function SendMessageModal({ open, onClose, onSend, isLoading, state, }) {
184
+ const t = useTranslations();
170
185
  const [message, setMessage] = useState('');
171
186
  const handleClose = () => {
172
187
  setMessage('');
173
188
  onClose();
174
189
  };
175
190
  const isRunning = state === AgentThreadState.PROCESSING || state === AgentThreadState.QUEUED;
176
- return (jsx(Modal, { open: open, onClose: handleClose, title: "Send message to thread", titleIcon: jsx(SendIcon, {}), footer: jsxs(Fragment, { children: [jsx("button", { className: "devic-state-btn", onClick: handleClose, type: "button", children: "Cancel" }), jsx("button", { className: "devic-state-btn devic-state-btn-primary", onClick: () => onSend(message), disabled: isLoading || !message.trim(), type: "button", children: "Send" })] }), children: jsxs("div", { style: { marginBottom: 12 }, children: [jsx("p", { style: { margin: '4px 0 12px', color: '#666', fontSize: 13 }, children: isRunning
177
- ? 'The agent is still running. Your message will be considered on its next turn, right after the current tool response.'
178
- : 'This will add your message and re-queue the thread so the agent runs again with it.' }), jsx("textarea", { className: "devic-approval-textarea", value: message, onChange: (e) => setMessage(e.target.value), placeholder: "Type a message to continue the thread...", onKeyDown: (e) => {
191
+ return (jsx(Modal, { open: open, onClose: handleClose, title: t('Send message to thread'), titleIcon: jsx(SendIcon, {}), footer: jsxs(Fragment, { children: [jsx("button", { className: "devic-state-btn", onClick: handleClose, type: "button", children: t('Cancel') }), jsx("button", { className: "devic-state-btn devic-state-btn-primary", onClick: () => onSend(message), disabled: isLoading || !message.trim(), type: "button", children: t('Send') })] }), children: jsxs("div", { style: { marginBottom: 12 }, children: [jsx("p", { style: { margin: '4px 0 12px', color: '#666', fontSize: 13 }, children: isRunning
192
+ ? t('The agent is still running. Your message will be considered on its next turn, right after the current tool response.')
193
+ : t('This will add your message and re-queue the thread so the agent runs again with it.') }), jsx("textarea", { className: "devic-approval-textarea", value: message, onChange: (e) => setMessage(e.target.value), placeholder: t('Type a message to continue the thread...'), onKeyDown: (e) => {
179
194
  if (e.key === 'Enter' && (e.ctrlKey || e.metaKey) && message.trim()) {
180
195
  e.preventDefault();
181
196
  onSend(message);
@@ -184,15 +199,18 @@ function SendMessageModal({ open, onClose, onSend, isLoading, state, }) {
184
199
  }
185
200
  /* ── Complete Thread Modal ── */
186
201
  function CompleteModal({ open, onClose, onComplete, }) {
202
+ const t = useTranslations();
187
203
  const [completionState, setCompletionState] = useState('terminated');
188
- return (jsx(Modal, { open: open, onClose: onClose, title: "Complete Execution Manually", titleIcon: jsx(WrenchIcon, {}), footer: jsxs(Fragment, { children: [jsx("button", { className: "devic-state-btn", onClick: onClose, type: "button", children: "Cancel" }), jsx("button", { className: "devic-state-btn devic-state-btn-danger", onClick: () => onComplete(completionState), type: "button", children: "Complete" })] }), children: jsxs("div", { style: { marginBottom: 12 }, children: [jsx("div", { style: { fontWeight: 600, marginBottom: 4 }, children: "Confirm Manual Completion" }), jsx("p", { style: { margin: '4px 0 12px', color: '#666', fontSize: 13 }, children: "You are about to manually complete this agent's execution." }), jsxs("div", { style: { marginBottom: 12 }, children: [jsx("div", { style: { fontWeight: 500, marginBottom: 6, fontSize: 13 }, children: "Complete as:" }), jsxs("select", { className: "devic-completion-select", value: completionState, onChange: (e) => setCompletionState(e.target.value), children: [jsx("option", { value: "terminated", children: "Terminated - Finish thread as manually terminated" }), jsx("option", { value: "completed", children: "Completed - Finish thread as successfully completed" }), jsx("option", { value: "failed", children: "Failed - Finish thread as failed or with errors" })] })] }), jsxs("div", { className: "devic-state-warning", children: [jsx(InfoIcon, {}), jsx("span", { children: "This action will immediately terminate all ongoing processes. The execution cannot be resumed after completion." })] })] }) }));
204
+ return (jsx(Modal, { open: open, onClose: onClose, title: t('Complete Execution Manually'), titleIcon: jsx(WrenchIcon, {}), footer: jsxs(Fragment, { children: [jsx("button", { className: "devic-state-btn", onClick: onClose, type: "button", children: t('Cancel') }), jsx("button", { className: "devic-state-btn devic-state-btn-danger", onClick: () => onComplete(completionState), type: "button", children: t('Complete') })] }), children: jsxs("div", { style: { marginBottom: 12 }, children: [jsx("div", { style: { fontWeight: 600, marginBottom: 4 }, children: t('Confirm Manual Completion') }), jsx("p", { style: { margin: '4px 0 12px', color: '#666', fontSize: 13 }, children: t("You are about to manually complete this agent's execution.") }), jsxs("div", { style: { marginBottom: 12 }, children: [jsx("div", { style: { fontWeight: 500, marginBottom: 6, fontSize: 13 }, children: t('Complete as:') }), jsxs("select", { className: "devic-completion-select", value: completionState, onChange: (e) => setCompletionState(e.target.value), children: [jsx("option", { value: "terminated", children: t('Terminated - Finish thread as manually terminated') }), jsx("option", { value: "completed", children: t('Completed - Finish thread as successfully completed') }), jsx("option", { value: "failed", children: t('Failed - Finish thread as failed or with errors') })] })] }), jsxs("div", { className: "devic-state-warning", children: [jsx(InfoIcon, {}), jsx("span", { children: t('This action will immediately terminate all ongoing processes. The execution cannot be resumed after completion.') })] })] }) }));
189
205
  }
190
206
  /* ── Confirm Modal (Pause/Resume) ── */
191
207
  function ConfirmModal({ open, onClose, onConfirm, title, icon, message, confirmText, }) {
192
- return (jsx(Modal, { open: open, onClose: onClose, title: title, titleIcon: icon, footer: jsxs(Fragment, { children: [jsx("button", { className: "devic-state-btn", onClick: onClose, type: "button", children: "Cancel" }), jsx("button", { className: "devic-state-btn devic-state-btn-primary", onClick: onConfirm, type: "button", children: confirmText })] }), children: jsx("p", { style: { margin: 0, color: '#666', fontSize: 14 }, children: message }) }));
208
+ const t = useTranslations();
209
+ return (jsx(Modal, { open: open, onClose: onClose, title: title, titleIcon: icon, footer: jsxs(Fragment, { children: [jsx("button", { className: "devic-state-btn", onClick: onClose, type: "button", children: t('Cancel') }), jsx("button", { className: "devic-state-btn devic-state-btn-primary", onClick: onConfirm, type: "button", children: confirmText })] }), children: jsx("p", { style: { margin: 0, color: '#666', fontSize: 14 }, children: message }) }));
193
210
  }
194
211
  /* ── Main ThreadStateTag ── */
195
212
  function ThreadStateTag({ state, threadId, agentName, showIcon = true, customIcon, pausedReason, approvalRejectedMessage, finishReason, onActionComplete, pauseUntil, subthreadCount, showAdminActions = false, apiKey, baseUrl, interactive = true, }) {
213
+ const t = useTranslations();
196
214
  const context = useOptionalDevicContext();
197
215
  const resolvedApiKey = apiKey || context?.apiKey;
198
216
  const resolvedTenantSession = context?.getTenantSession;
@@ -241,9 +259,9 @@ function ThreadStateTag({ state, threadId, agentName, showIcon = true, customIco
241
259
  });
242
260
  }, [resolvedApiKey, resolvedTenantSession, resolvedBaseUrl]);
243
261
  // Config
244
- const config = getStateConfig(state, subthreadCount);
262
+ const config = getStateConfig(t, state, subthreadCount);
245
263
  if (!state) {
246
- return jsx("span", { className: "devic-state-tag", "data-color": "default", children: "Unknown" });
264
+ return (jsx("span", { className: "devic-state-tag", "data-color": "default", children: t('Unknown') }));
247
265
  }
248
266
  // Icon
249
267
  const renderIcon = () => {
@@ -258,26 +276,31 @@ function ThreadStateTag({ state, threadId, agentName, showIcon = true, customIco
258
276
  const getTooltipContent = () => {
259
277
  switch (state) {
260
278
  case AgentThreadState.PAUSED_FOR_APPROVAL:
261
- return 'Agent is waiting for approval to resume execution';
279
+ return t('Agent is waiting for approval to resume execution');
262
280
  case AgentThreadState.PAUSED_FOR_RESUME:
263
281
  if (pauseUntil) {
264
282
  const timeDiff = new Date(pauseUntil).getTime() - Date.now();
265
283
  const hours = Math.floor(timeDiff / 3600000);
266
284
  const minutes = Math.floor(timeDiff / 60000);
267
- const timeStr = hours > 0 ? `${hours} hours` : `${minutes} minutes`;
268
- return `Agent paused, will resume at ${new Date(pauseUntil).toLocaleString()} (${timeStr})`;
285
+ const timeStr = hours > 0
286
+ ? t('{count} hours', { count: hours })
287
+ : t('{count} minutes', { count: minutes });
288
+ return t('Agent paused, will resume at {when} ({in})', {
289
+ when: new Date(pauseUntil).toLocaleString(),
290
+ in: timeStr,
291
+ });
269
292
  }
270
- return 'Agent paused, will resume at a scheduled time';
293
+ return t('Agent paused, will resume at a scheduled time');
271
294
  case AgentThreadState.WAITING_FOR_RESPONSE:
272
- return pausedReason || 'Agent is waiting for response';
295
+ return pausedReason || t('Agent is waiting for response');
273
296
  case AgentThreadState.COMPLETED:
274
297
  case AgentThreadState.FAILED:
275
298
  case AgentThreadState.TERMINATED:
276
- return finishReason || 'Manually finished thread';
299
+ return finishReason || t('Manually finished thread');
277
300
  case AgentThreadState.APPROVAL_REJECTED:
278
- return approvalRejectedMessage || 'Approval was rejected';
301
+ return approvalRejectedMessage || t('Approval was rejected');
279
302
  case AgentThreadState.GUARDRAIL_TRIGGER:
280
- return 'Agent execution paused due to guardrail trigger';
303
+ return t('Agent execution paused due to guardrail trigger');
281
304
  default:
282
305
  return null;
283
306
  }
@@ -290,7 +313,7 @@ function ThreadStateTag({ state, threadId, agentName, showIcon = true, customIco
290
313
  setThreadExplanation(null);
291
314
  const client = getClient();
292
315
  if (!client) {
293
- setThreadExplanation('API key not configured.');
316
+ setThreadExplanation(t('API key not configured.'));
294
317
  setIsLoadingExplanation(false);
295
318
  return;
296
319
  }
@@ -299,7 +322,7 @@ function ThreadStateTag({ state, threadId, agentName, showIcon = true, customIco
299
322
  setThreadExplanation(explanation);
300
323
  }
301
324
  catch {
302
- setThreadExplanation('Could not obtain the thread explanation.');
325
+ setThreadExplanation(t('Could not obtain the thread explanation.'));
303
326
  }
304
327
  finally {
305
328
  setIsLoadingExplanation(false);
@@ -395,7 +418,7 @@ function ThreadStateTag({ state, threadId, agentName, showIcon = true, customIco
395
418
  dropdownItems.push({
396
419
  key: 'complete',
397
420
  icon: jsx(WrenchIcon, {}),
398
- label: 'Complete manually',
421
+ label: t('Complete manually'),
399
422
  onClick: () => { setDropdownOpen(false); setCompleteModalOpen(true); },
400
423
  });
401
424
  }
@@ -403,7 +426,7 @@ function ThreadStateTag({ state, threadId, agentName, showIcon = true, customIco
403
426
  dropdownItems.push({
404
427
  key: 'pause',
405
428
  icon: jsx(PauseIcon, {}),
406
- label: 'Pause',
429
+ label: t('Pause'),
407
430
  onClick: () => { setDropdownOpen(false); setPauseModalOpen(true); },
408
431
  });
409
432
  }
@@ -411,7 +434,7 @@ function ThreadStateTag({ state, threadId, agentName, showIcon = true, customIco
411
434
  dropdownItems.push({
412
435
  key: 'resume',
413
436
  icon: jsx(PlayIcon, {}),
414
- label: 'Resume',
437
+ label: t('Resume'),
415
438
  onClick: () => { setDropdownOpen(false); setResumeModalOpen(true); },
416
439
  });
417
440
  }
@@ -419,7 +442,7 @@ function ThreadStateTag({ state, threadId, agentName, showIcon = true, customIco
419
442
  dropdownItems.push({
420
443
  key: 'review',
421
444
  icon: jsx(EyeIcon, {}),
422
- label: 'Review',
445
+ label: t('Review'),
423
446
  onClick: () => { setDropdownOpen(false); setReviewModalOpen(true); },
424
447
  });
425
448
  }
@@ -427,14 +450,14 @@ function ThreadStateTag({ state, threadId, agentName, showIcon = true, customIco
427
450
  dropdownItems.push({
428
451
  key: 'send_message',
429
452
  icon: jsx(SendIcon, {}),
430
- label: 'Send message...',
453
+ label: t('Send message...'),
431
454
  onClick: () => { setDropdownOpen(false); setSendMessageModalOpen(true); },
432
455
  });
433
456
  }
434
457
  dropdownItems.push({
435
458
  key: 'explain',
436
459
  icon: jsx(LightbulbIcon, {}),
437
- label: 'Explain thread...',
460
+ label: t('Explain thread...'),
438
461
  onClick: handleExplain,
439
462
  });
440
463
  const canInteract = interactive && threadId;
@@ -464,7 +487,7 @@ function ThreadStateTag({ state, threadId, agentName, showIcon = true, customIco
464
487
  }
465
488
  setShowTooltip(true);
466
489
  }
467
- }, onMouseLeave: () => setShowTooltip(false), children: [renderIcon(), config.text, canInteract && (jsx("span", { className: "devic-state-tag-caret", children: jsx(CaretDownIcon, {}) }))] }), showTooltip && tooltipContent && !dropdownOpen && createPortal(jsx("div", { className: "devic-state-tooltip-portal", style: tooltipStyle, children: tooltipContent }), document.body), dropdownOpen && canInteract && createPortal(jsx("div", { ref: dropdownRef, className: "devic-state-dropdown-portal", style: dropdownStyle, children: dropdownItems.map((item) => (jsxs("button", { className: "devic-state-dropdown-item", onClick: (e) => { e.stopPropagation(); item.onClick(); }, type: "button", children: [jsx("span", { className: "devic-state-dropdown-item-icon", children: item.icon }), item.label] }, item.key))) }), document.body), jsx(ExplainModal, { open: explainModalOpen, onClose: () => setExplainModalOpen(false), explanation: threadExplanation, isLoading: isLoadingExplanation, agentName: agentName }), jsx(CompleteModal, { open: completeModalOpen, onClose: () => setCompleteModalOpen(false), onComplete: handleComplete }), jsx(ConfirmModal, { open: pauseModalOpen, onClose: () => setPauseModalOpen(false), onConfirm: handlePause, title: "Pause Thread", icon: jsx(PauseIcon, {}), message: "You are about to pause this queued thread. It can be resumed later.", confirmText: "Pause" }), jsx(ConfirmModal, { open: resumeModalOpen, onClose: () => setResumeModalOpen(false), onConfirm: handleResume, title: "Resume Thread", icon: jsx(PlayIcon, {}), message: "You are about to resume this thread. It will go back to the queue and be processed when possible.", confirmText: "Resume" }), jsx(ApprovalModal, { open: reviewModalOpen, onClose: () => setReviewModalOpen(false), onApprove: handleApproval, isLoading: isLoadingApproval, pausedReason: pausedReason }), jsx(SendMessageModal, { open: sendMessageModalOpen, onClose: () => setSendMessageModalOpen(false), onSend: handleSendMessage, isLoading: isSendingMessage, state: state })] }));
490
+ }, onMouseLeave: () => setShowTooltip(false), children: [renderIcon(), config.text, canInteract && (jsx("span", { className: "devic-state-tag-caret", children: jsx(CaretDownIcon, {}) }))] }), showTooltip && tooltipContent && !dropdownOpen && createPortal(jsx("div", { className: "devic-state-tooltip-portal", style: tooltipStyle, children: tooltipContent }), document.body), dropdownOpen && canInteract && createPortal(jsx("div", { ref: dropdownRef, className: "devic-state-dropdown-portal", style: dropdownStyle, children: dropdownItems.map((item) => (jsxs("button", { className: "devic-state-dropdown-item", onClick: (e) => { e.stopPropagation(); item.onClick(); }, type: "button", children: [jsx("span", { className: "devic-state-dropdown-item-icon", children: item.icon }), item.label] }, item.key))) }), document.body), jsx(ExplainModal, { open: explainModalOpen, onClose: () => setExplainModalOpen(false), explanation: threadExplanation, isLoading: isLoadingExplanation, agentName: agentName }), jsx(CompleteModal, { open: completeModalOpen, onClose: () => setCompleteModalOpen(false), onComplete: handleComplete }), jsx(ConfirmModal, { open: pauseModalOpen, onClose: () => setPauseModalOpen(false), onConfirm: handlePause, title: t('Pause Thread'), icon: jsx(PauseIcon, {}), message: t('You are about to pause this queued thread. It can be resumed later.'), confirmText: t('Pause') }), jsx(ConfirmModal, { open: resumeModalOpen, onClose: () => setResumeModalOpen(false), onConfirm: handleResume, title: t('Resume Thread'), icon: jsx(PlayIcon, {}), message: t('You are about to resume this thread. It will go back to the queue and be processed when possible.'), confirmText: t('Resume') }), jsx(ApprovalModal, { open: reviewModalOpen, onClose: () => setReviewModalOpen(false), onApprove: handleApproval, isLoading: isLoadingApproval, pausedReason: pausedReason }), jsx(SendMessageModal, { open: sendMessageModalOpen, onClose: () => setSendMessageModalOpen(false), onSend: handleSendMessage, isLoading: isSendingMessage, state: state })] }));
468
491
  }
469
492
 
470
493
  export { ThreadStateTag };