Skip to content

Commit 6a3eb79

Browse files
authored
Create UI components for Assistant-UI connection monitoring (#1549)
Part of OPS-2896. The new UI components are not actively rendered yet; this PR is a pre-requisite for [PR-1548.](#1548)
1 parent 2609234 commit 6a3eb79

File tree

11 files changed

+142
-27
lines changed

11 files changed

+142
-27
lines changed

packages/react-ui/public/locales/en/translation.json

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,6 @@
1717
"Contact Support": "Contact Support",
1818
"AI Assistant": "AI Assistant",
1919
"Enable AI": "Enable AI",
20-
"Choose your AI provider": "Choose your AI provider",
21-
"Select an option": "Select an option",
22-
"Model": "Model",
23-
"API key": "API key",
24-
"Base URL": "Base URL",
25-
"Advanced settings": "Advanced settings",
26-
"Provider Settings": "Provider Settings",
27-
"Model Settings": "Model Settings",
2820
"Save": "Save",
2921
"Valid Connection": "Valid Connection",
3022
"Loading chat...": "Loading chat...",
@@ -84,6 +76,7 @@
8476
"Use a static pre-defined value": "Use a static pre-defined value",
8577
"Dynamic": "Dynamic",
8678
"Static values stay the same, while dynamic values update based on data from other steps": "Static values stay the same, while dynamic values update based on data from other steps",
79+
"Select an option": "Select an option",
8780
"Custom TypeScript Code": "Custom TypeScript Code",
8881
"Loop on Items": "Loop on Items",
8982
"Condition": "Condition",
@@ -142,6 +135,7 @@
142135
"{invalidSteps, plural, =0 {no incomplete steps} =1 {Complete 1 step} other {Complete # steps}}": "{invalidSteps, plural, =0 {no incomplete steps} =1 {Complete 1 step} other {Complete # steps}}",
143136
"Test Workflow": "Test Workflow",
144137
"Please test the trigger first": "Please test the trigger first",
138+
"Test run limits": "Test run limits",
145139
"Use as Draft": "Use as Draft",
146140
"Are you sure?": "Are you sure?",
147141
"Your current draft version will be overwritten with": "Your current draft version will be overwritten with",
@@ -150,10 +144,12 @@
150144
"Viewing": "Viewing",
151145
"View": "View",
152146
"Error, please try again.": "Error, please try again.",
147+
"Action limit reached.": "Action limit reached.",
153148
"Duration": "Duration",
154149
"Run Details": "Run Details",
155150
"There are no logs captured for this run.": "There are no logs captured for this run.",
156151
"Logs are kept for {days} days after execution and then deleted.": "Logs are kept for {days} days after execution and then deleted.",
152+
"Run Stopped due to Action Limits": "Run Stopped due to Action Limits",
157153
"Workflow Run was stopped": "Workflow Run was stopped",
158154
"Run Succeeded": "Run Succeeded",
159155
"Run Failed": "Run Failed",
@@ -162,6 +158,7 @@
162158
"Run exceeded {timeout} seconds, try to optimize your steps.": "Run exceeded {timeout} seconds, try to optimize your steps.",
163159
"Run failed for an unknown reason, contact support.": "Run failed for an unknown reason, contact support.",
164160
"Unknown status": "Unknown status",
161+
"Configure limit": "Configure limit",
165162
"Took": "Took",
166163
"Recent Runs": "Recent Runs",
167164
"No runs found": "No runs found",
@@ -226,11 +223,16 @@
226223
"This branch will be removed.": "This branch will be removed.",
227224
"Add new": "Add new",
228225
"Where": "Where",
226+
"Copied to clipboard": "Copied to clipboard",
227+
"Test URL": "Test URL",
228+
"Copy URL": "Copy URL",
229+
"This URL generates sample data and does NOT trigger the flow.": "This URL generates sample data and does NOT trigger the flow.",
229230
"Step output": "Step output",
230231
"Sample output": "Sample output",
231232
"Sample output info": "Sample output info",
232233
"Sample data is for building and testing only - scheduled runs and test workflow are using the real step output.": "Sample data is for building and testing only - scheduled runs and test workflow are using the real step output.",
233234
"Sample data is too large. The maximum allowed size is {maxKb} KB.": "Sample data is too large. The maximum allowed size is {maxKb} KB.",
235+
"Unknown Error": "Unknown Error",
234236
"Test Step": "Test Step",
235237
"Warning. Executing this step may modify resources in your environment.": "Warning. Executing this step may modify resources in your environment.",
236238
"Please review the details before proceeding.": "Please review the details before proceeding.",
@@ -289,7 +291,6 @@
289291
"I would like to use predefined App Credentials": "I would like to use predefined App Credentials",
290292
"Name can only contain letters, numbers and underscores": "Name can only contain letters, numbers and underscores",
291293
"Unknown": "Unknown",
292-
"Exit Run": "Exit Run",
293294
"Triggered": "Triggered",
294295
"Manual run": "Manual run",
295296
"Test run": "Test run",
@@ -448,21 +449,24 @@
448449
"Running version": "Running version",
449450
"Error loading version": "Error loading version",
450451
"Newer version is available": "Newer version is available",
451-
"You are on the latest version": "You are on the latest version",
452+
"Learn how to update on the latest version": "Learn how to update on the latest version",
452453
"Learn how to update": "Learn how to update",
453454
"Search model...": "Search model...",
454455
"No model found": "No model found",
455456
"Add step context...": "Add step context...",
456457
"It looks like AI hasn’t been configured in OpenOps yet.": "It looks like AI hasn’t been configured in OpenOps yet.",
457458
"Please go to ": "Please go to ",
458459
" to complete the setup.": " to complete the setup.",
459-
"AI Chat": "AI Chat",
460-
"Toggle AI Chat": "Toggle AI Chat",
461460
"New chat": "New chat",
462461
"Generating ...": "Generating ...",
463462
"Use code": "Use code",
463+
"Loading diagram...": "Loading diagram...",
464464
"Inject command": "Inject command",
465+
"Rendering diagram...": "Rendering diagram...",
466+
"AI Chat": "AI Chat",
467+
"Toggle AI Chat": "Toggle AI Chat",
465468
"How can I help you today?": "How can I help you today?",
469+
"The AI is taking a bit longer than expected. Please wait...": "The AI is taking a bit longer than expected. Please wait...",
466470
"Scroll to bottom": "Scroll to bottom",
467471
"Write a message...": "Write a message...",
468472
"Send": "Send",
@@ -477,6 +481,7 @@
477481
"Note: ": "Note: ",
478482
"Exploring template catalog might not work if you're not running Openops over a secure HTTPS connection or if you configured your browser to block 3rd party cookies (some browsers like Safari block 3rd party cookies by default).": "Exploring template catalog might not work if you're not running Openops over a secure HTTPS connection or if you configured your browser to block 3rd party cookies (some browsers like Safari block 3rd party cookies by default).",
479483
"Click to start editing": "Click to start editing",
484+
"Upgrade": "Upgrade",
480485
"We’re glad to give back!": "We’re glad to give back!",
481486
"This open-source version is free to use.\n Want more power? Explore our paid plans.": "This open-source version is free to use.\n Want more power? Explore our paid plans.",
482487
"See plans": "See plans",
@@ -528,23 +533,21 @@
528533
"Download File": "Download File",
529534
"Apply": "Apply",
530535
"Paste sample data here": "Paste sample data here",
531-
"Copied to clipboard": "Copied to clipboard",
532536
"File is not available after execution.": "File is not available after execution.",
533537
"No workflows created yet": "No workflows created yet",
534538
"Automate your FinOps processes, pick a template or start from scratch in order to see here your workflows stats": "Automate your FinOps processes, pick a template or start from scratch in order to see here your workflows stats",
535539
"Workflow triggered successfully.": "Workflow triggered successfully.",
536540
"Check the Runs page for details": "Check the Runs page for details",
537-
"Configure limit": "Configure limit",
541+
"Current version: {currentVersion}. Newer version is available, go to settings to update": "Current version: {currentVersion}. Newer version is available, go to settings to update",
542+
"Coming soon": "Coming soon",
538543
"Set Action Limits": "Set Action Limits",
539-
"Run Stopped due to Action Limits": "Run Stopped due to Action Limits",
544+
"No Actions to Limit": "No Actions to Limit",
540545
"Workflows with loops may trigger the same action repeatedly. To prevent unintended activity during testing, we recommend setting execution limits per action.": "Workflows with loops may trigger the same action repeatedly. To prevent unintended activity during testing, we recommend setting execution limits per action.",
546+
"This workflow doesn’t include any actions that require execution limits. If loops or repeated steps are added later, you’ll be able to set limits here to prevent unintended behavior during testing.": "This workflow doesn’t include any actions that require execution limits. If loops or repeated steps are added later, you’ll be able to set limits here to prevent unintended behavior during testing.",
541547
"Enable run limits": "Enable run limits",
542548
"Select all": "Select all",
543549
"All actions": "All actions",
544550
"Toggle {{block}} {{action}}": "Toggle {{block}} {{action}}",
545-
"No actions available.": "No actions available.",
546-
"Current version: {currentVersion}. Newer version is available, go to settings to update": "Current version: {currentVersion}. Newer version is available, go to settings to update",
547-
"Coming soon": "Coming soon",
548551
"Input": "Input",
549552
"View input data": "View input data",
550553
"Output": "Output",

packages/ui-components/src/components/ai-chat-container/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,4 @@ export * from './ai-model-selector';
22
export * from './ai-scope-selector';
33
export * from './assistant-ui-chat-container';
44
export * from './no-ai-enabled-popover';
5-
export * from './step-settings-assistant-ui-chat-container';
65
export * from './types';

packages/ui-components/src/components/assistant-ui/assistant-ui-chat-container.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ import { MarkdownCodeVariations } from '../custom';
88
import { AssistantTopBar, AssistantTopBarProps } from './assistant-top-bar';
99
import { Thread, ThreadProps } from './thread';
1010
import { ThreadExtraContextProvider } from './thread-extra-context';
11+
import { ConnectionStatusProps } from './types';
1112

1213
type AssistantUiChatContainerProps = {
1314
runtime: AssistantRuntime;
1415
toolComponents?: Record<string, ReactNode>;
1516
handleInject?: (codeContent: string | SourceCode) => void;
16-
} & AssistantTopBarProps &
17+
} & ConnectionStatusProps &
18+
AssistantTopBarProps &
1719
ThreadProps;
1820

1921
const AssistantUiChatContainer = ({
@@ -29,6 +31,8 @@ const AssistantUiChatContainer = ({
2931
children,
3032
handleInject,
3133
toolComponents,
34+
isShowingSlowWarning,
35+
connectionError,
3236
}: AssistantUiChatContainerProps) => {
3337
const codeVariation = useMemo(() => {
3438
return handleInject
@@ -55,6 +59,8 @@ const AssistantUiChatContainer = ({
5559
selectedModel={selectedModel}
5660
isModelSelectorLoading={isModelSelectorLoading}
5761
theme={theme}
62+
isShowingSlowWarning={isShowingSlowWarning}
63+
connectionError={connectionError}
5864
/>
5965
</ThreadExtraContextProvider>
6066
</AssistantRuntimeProvider>

packages/ui-components/src/components/ai-chat-container/step-settings-assistant-ui-chat-container.tsx renamed to packages/ui-components/src/components/assistant-ui/step-settings-assistant-ui-chat-container.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@ import { ExpandIcon, MinimizeIcon } from 'lucide-react';
66
import { useRef } from 'react';
77
import { cn } from '../../lib/cn';
88
import { Button } from '../../ui/button';
9-
import { AssistantUiChatContainer } from '../assistant-ui/assistant-ui-chat-container';
9+
import {
10+
AI_CHAT_CONTAINER_SIZES,
11+
AiCliChatContainerSizeState,
12+
} from '../ai-chat-container/types';
1013
import { TooltipWrapper } from '../tooltip-wrapper';
11-
import { AI_CHAT_CONTAINER_SIZES, AiCliChatContainerSizeState } from './types';
14+
import { AssistantUiChatContainer } from './assistant-ui-chat-container';
15+
import { ConnectionStatusProps } from './types';
1216

1317
const COLLAPSED_HEIGHT = 57;
1418
const DOCKED_HEIGHT = 450;
@@ -34,7 +38,7 @@ type StepSettingsAssistantUiChatContainerProps = {
3438
theme: Theme;
3539
handleInject: (code: string | SourceCode) => void;
3640
showFullWidth: boolean;
37-
};
41+
} & ConnectionStatusProps;
3842

3943
const StepSettingsAssistantUiChatContainer = ({
4044
parentHeight,
@@ -53,6 +57,8 @@ const StepSettingsAssistantUiChatContainer = ({
5357
theme,
5458
handleInject,
5559
showFullWidth,
60+
isShowingSlowWarning,
61+
connectionError,
5662
}: StepSettingsAssistantUiChatContainerProps) => {
5763
const containerRef = useRef<HTMLDivElement>(null);
5864

@@ -100,6 +106,8 @@ const StepSettingsAssistantUiChatContainer = ({
100106
availableModels={availableModels}
101107
theme={theme}
102108
title={t('AI Chat')}
109+
isShowingSlowWarning={isShowingSlowWarning}
110+
connectionError={connectionError}
103111
>
104112
<div
105113
className="text-md dark:text-primary items-center font-bold flex"
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { AlertTriangle } from 'lucide-react';
2+
import { FC } from 'react';
3+
4+
export const ConnectionError: FC<{ error: string }> = ({ error }) => {
5+
return (
6+
<div className="w-full max-w-2xl mb-3">
7+
<div className="flex items-center gap-2 px-4 py-3 rounded-lg bg-red-50 dark:bg-red-950/20 border border-red-200 dark:border-red-800">
8+
<div className="flex-shrink-0">
9+
<AlertTriangle className="w-5 h-5 text-red-600 dark:text-red-400" />
10+
</div>
11+
<div className="flex-1 text-sm text-red-800 dark:text-red-200">
12+
{error}
13+
</div>
14+
</div>
15+
</div>
16+
);
17+
};
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { t } from 'i18next';
2+
import { AlertCircle } from 'lucide-react';
3+
import { FC } from 'react';
4+
5+
export const ConnectionSlowWarning: FC = () => {
6+
return (
7+
<div className="w-full max-w-2xl mb-3">
8+
<div className="flex items-center gap-2 px-4 py-3 rounded-lg bg-amber-50 dark:bg-amber-950/20 border border-amber-200 dark:border-amber-800">
9+
<div className="flex-shrink-0">
10+
<AlertCircle className="w-5 h-5 text-amber-600 dark:text-amber-400" />
11+
</div>
12+
<div className="flex-1 text-sm text-amber-800 dark:text-amber-200">
13+
{t('The AI is taking a bit longer than expected. Please wait...')}
14+
</div>
15+
</div>
16+
</div>
17+
);
18+
};

packages/ui-components/src/components/assistant-ui/thread/thread.tsx

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ import { MarkdownText } from '../markdown-text';
2525
import { useThreadExtraContext } from '../thread-extra-context';
2626
import { ToolFallback } from '../tool-fallback';
2727
import { TooltipIconButton } from '../tooltip-icon-button';
28+
import { ConnectionStatusProps } from '../types';
29+
import { ConnectionError } from './connection-error';
30+
import { ConnectionSlowWarning } from './connection-slow-warning';
2831
import { ReasoningPart } from './reasoning-part';
2932

3033
const MarkdownTextWrapper = memo(({ theme, ...props }: any) => {
@@ -48,14 +51,17 @@ AssistantMessageWrapper.displayName = 'AssistantMessageWrapper';
4851

4952
export type ThreadProps = {
5053
theme: Theme;
51-
} & ComposerProps;
54+
} & ConnectionStatusProps &
55+
ComposerProps;
5256

5357
export const Thread = ({
5458
theme,
5559
availableModels,
5660
selectedModel,
5761
onModelSelected,
5862
isModelSelectorLoading,
63+
isShowingSlowWarning,
64+
connectionError,
5965
}: ThreadProps) => {
6066
const messageComponents = useMemo(
6167
() => ({
@@ -72,6 +78,8 @@ export const Thread = ({
7278

7379
<ThreadPrimitive.Messages components={messageComponents} />
7480

81+
{isShowingSlowWarning && <ConnectionSlowWarning />}
82+
7583
<ThreadPrimitive.If running>
7684
<div className="w-full mb-2">
7785
<div className="flex items-center text-slate-800 dark:text-slate-50">
@@ -82,6 +90,8 @@ export const Thread = ({
8290
</div>
8391
</ThreadPrimitive.If>
8492

93+
{connectionError && <ConnectionError error={connectionError} />}
94+
8595
<ThreadPrimitive.If empty={false}>
8696
<div className="min-h-8 flex-grow" />
8797
</ThreadPrimitive.If>
@@ -93,6 +103,7 @@ export const Thread = ({
93103
selectedModel={selectedModel}
94104
onModelSelected={onModelSelected}
95105
isModelSelectorLoading={isModelSelectorLoading}
106+
connectionError={connectionError}
96107
/>
97108
</div>
98109
</ThreadPrimitive.Viewport>
@@ -128,23 +139,29 @@ const ThreadWelcome: FC = () => {
128139
);
129140
};
130141

131-
type ComposerProps = AiModelSelectorProps;
142+
type ComposerProps = AiModelSelectorProps & {
143+
connectionError?: string | null;
144+
};
132145

133146
const Composer = ({
134147
availableModels,
135148
selectedModel,
136149
onModelSelected,
137150
isModelSelectorLoading,
151+
connectionError,
138152
}: ComposerProps) => {
153+
const isDisabled = !!connectionError;
154+
139155
return (
140156
<ComposerPrimitive.Root className="relative focus-within:border-ring/20 flex w-full flex-wrap items-end rounded-lg border bg-inherit px-2.5 shadow-sm transition-colors ease-in pb-9">
141157
<ComposerPrimitive.Input
142158
rows={1}
143159
autoFocus
144160
placeholder={t('Write a message...')}
145161
className="placeholder:text-muted-foreground max-h-40 flex-grow resize-none border-none bg-transparent px-2 py-4 text-sm outline-none focus:ring-0 disabled:cursor-not-allowed"
162+
disabled={isDisabled}
146163
/>
147-
<ComposerAction />
164+
<ComposerAction isDisabled={isDisabled} />
148165

149166
<AiModelSelector
150167
availableModels={availableModels}
@@ -157,7 +174,7 @@ const Composer = ({
157174
);
158175
};
159176

160-
const ComposerAction: FC = () => {
177+
const ComposerAction: FC<{ isDisabled: boolean }> = ({ isDisabled }) => {
161178
return (
162179
<>
163180
<ThreadPrimitive.If running={false}>
@@ -166,6 +183,7 @@ const ComposerAction: FC = () => {
166183
tooltip="Send"
167184
variant="default"
168185
className="my-2.5 size-8 p-2 transition-opacity ease-in"
186+
disabled={isDisabled}
169187
>
170188
<SendHorizontalIcon />
171189
</TooltipIconButton>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export type ConnectionStatusProps = {
2+
isShowingSlowWarning?: boolean;
3+
connectionError?: string | null;
4+
};

packages/ui-components/src/components/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export * from './ai-chat-container';
22
export * from './assistant-ui/assistant-top-bar';
33
export * from './assistant-ui/assistant-ui-chat-container';
4+
export * from './assistant-ui/step-settings-assistant-ui-chat-container';
45
export * from './assistant-ui/thread';
56
export * from './assistant-ui/thread-extra-context';
67
export * from './block-icon';

0 commit comments

Comments
 (0)