Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Release hotfixes #290

Merged
merged 9 commits into from
Jan 14, 2025
52 changes: 52 additions & 0 deletions src/__fixtures__/confirmation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { ToolConfirmationPauseReason } from "../services/refact";

export const CONFIRMATIONAL_PAUSE_REASONS_WITH_PATH: ToolConfirmationPauseReason[] =
[
{
command: "SELECT *",
rule: "*",
type: "confirmation",
tool_call_id: "1",
integr_config_path:
"\\\\?\\d:\\work\\refact.ai\\refact-lsp\\.refact\\integrations\\postgres.yaml",
},
];
export const CONFIRMATIONAL_PAUSE_REASONS: ToolConfirmationPauseReason[] = [
{
command: "patch",
rule: "default",
type: "confirmation",
tool_call_id: "1",
integr_config_path: null,
},
];

export const DENIAL_PAUSE_REASONS_WITH_PATH: ToolConfirmationPauseReason[] = [
{
command: "SELECT *",
rule: "*",
type: "denial",
tool_call_id: "1",
integr_config_path:
"\\\\?\\d:\\work\\refact.ai\\refact-lsp\\.refact\\integrations\\postgres.yaml",
},
];

export const MIXED_PAUSE_REASONS: ToolConfirmationPauseReason[] = [
{
command: "SELECT *",
rule: "*",
type: "denial",
tool_call_id: "1",
integr_config_path:
"\\\\?\\d:\\work\\refact.ai\\refact-lsp\\.refact\\integrations\\postgres.yaml",
},
{
command: "DROP *",
rule: "*",
type: "confirmation",
tool_call_id: "1",
integr_config_path:
"\\\\?\\d:\\work\\refact.ai\\refact-lsp\\.refact\\integrations\\postgres.yaml",
},
];
2 changes: 1 addition & 1 deletion src/components/ChatContent/ContextFiles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const Markdown: React.FC<{
return (
<ReactMarkDown
components={{
code({ style: _style, ...codeProps }) {
code({ style: _style, color: _color, ...codeProps }) {
return (
<MarkdownCodeBlock
{...codeProps}
Expand Down
6 changes: 4 additions & 2 deletions src/components/ChatForm/ChatForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
selectIsStreaming,
selectIsWaiting,
selectMessages,
selectPreventSend,
selectToolUse,
} from "../../features/Chat";

Expand Down Expand Up @@ -64,12 +65,13 @@ export const ChatForm: React.FC<ChatFormProps> = ({
const { disableInput } = useAgentUsage();
const isOnline = useIsOnline();
const messages = useAppSelector(selectMessages);
const preventSend = useAppSelector(selectPreventSend);

const disableSend = useMemo(() => {
// TODO: if interrupting chat some errors can occur
if (messages.length === 0) return false;
return isWaiting || isStreaming || !isOnline;
}, [isOnline, isStreaming, isWaiting, messages]);
return isWaiting || isStreaming || !isOnline || preventSend;
}, [isOnline, isStreaming, isWaiting, preventSend, messages]);

const { processAndInsertImages } = useAttachedImages();
const handlePastingFile = useCallback(
Expand Down
75 changes: 75 additions & 0 deletions src/components/ChatForm/ToolConfirmation.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import React from "react";
import type { Meta, StoryObj } from "@storybook/react";
import { ToolConfirmation } from "./ToolConfirmation";
import { Provider } from "react-redux";
import { setUpStore } from "../../app/store";
import { Theme } from "../Theme";
import { ToolConfirmationPauseReason } from "../../services/refact";
import { AbortControllerProvider } from "../../contexts/AbortControllers";
import {
CONFIRMATIONAL_PAUSE_REASONS,
CONFIRMATIONAL_PAUSE_REASONS_WITH_PATH,
DENIAL_PAUSE_REASONS_WITH_PATH,
MIXED_PAUSE_REASONS,
} from "../../__fixtures__/confirmation";

const MockedStore: React.FC<{
pauseReasons: ToolConfirmationPauseReason[];
}> = ({ pauseReasons }) => {
const store = setUpStore({
confirmation: {
pauseReasons,
pause: true,
status: {
wasInteracted: false,
confirmationStatus: false,
},
},
});

return (
<Provider store={store}>
<AbortControllerProvider>
<Theme accentColor="gray">
<ToolConfirmation pauseReasons={pauseReasons} />
</Theme>
</AbortControllerProvider>
</Provider>
);
};

const meta: Meta<typeof MockedStore> = {
title: "ToolConfirmation",
component: MockedStore,
args: {
pauseReasons: [],
},
};

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
pauseReasons: CONFIRMATIONAL_PAUSE_REASONS_WITH_PATH,
},
};

export const WithDenial: Story = {
args: {
pauseReasons: DENIAL_PAUSE_REASONS_WITH_PATH,
},
};

export const Patch: Story = {
args: {
pauseReasons: CONFIRMATIONAL_PAUSE_REASONS,
},
};

export const Mixed: Story = {
args: {
pauseReasons: MIXED_PAUSE_REASONS,
},
};
14 changes: 10 additions & 4 deletions src/components/ChatForm/ToolConfirmation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,21 @@ export const ToolConfirmation: React.FC<ToolConfirmationProps> = ({
gap="4"
>
<Flex align="start" direction="column" gap="3" maxWidth="100%">
<Text className={styles.ToolConfirmationHeading}>
🔨 Model {allConfirmational ? "wants" : "tried"} to run:
</Text>
<Flex
align="baseline"
gap="1"
className={styles.ToolConfirmationHeading}
>
<Text as="span">⚠️</Text>
<Text>Model {allConfirmational ? "wants" : "tried"} to run:</Text>
</Flex>
{commands.map((command, i) => (
<Markdown
key={toolCallIds[i]}
>{`${"```bash\n"}${command}${"\n```"}`}</Markdown>
))}
<Text className={styles.ToolConfirmationText}>
<Markdown>{message.concat("\n\n")}</Markdown>
<Markdown color="indigo">{message.concat("\n\n")}</Markdown>
{maybeIntegrationPath && (
<Text className={styles.ToolConfirmationText} mt="3">
You can modify the ruleset on{" "}
Expand All @@ -114,6 +119,7 @@ export const ToolConfirmation: React.FC<ToolConfirmationProps> = ({
}),
);
}}
color="indigo"
>
Configuration Page
</Link>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,26 @@ export const IntegrationAvailability: FC<IntegrationAvailabilityProps> = ({
// TODO: temporal solution to hide the switch for isolated mode
if (fieldName === "when_isolated") return null;

const handleLabelClick = () => {
MarcMcIntosh marked this conversation as resolved.
Show resolved Hide resolved
handleSwitchChange(!value);
};

return (
<Flex style={{ marginBottom: "0.75rem" }}>
<Flex align="center" justify="between" gap="1">
<label htmlFor={`switch-${fieldName}`}>
<CustomLabel
label={toPascalCase(
fieldName === "on_your_laptop" ? "enabled" : "run_in_docker",
)}
/>
</label>
<Flex align="center" justify="between" gap="3">
<Switch
id={`switch-${fieldName}`}
size="2"
ml="2"
checked={value}
onCheckedChange={handleSwitchChange}
/>
<label htmlFor={`switch-${fieldName}`} onClick={handleLabelClick}>
MarcMcIntosh marked this conversation as resolved.
Show resolved Hide resolved
<CustomLabel
label={toPascalCase(
fieldName === "on_your_laptop" ? "enable" : "run_in_docker",
)}
/>
</label>
</Flex>
</Flex>
);
Expand Down
65 changes: 39 additions & 26 deletions src/components/IntegrationsView/IntegrationForm/IntegrationForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -227,26 +227,28 @@ export const IntegrationForm: FC<IntegrationFormProps> = ({
id={`form-${integration.data.integr_name}`}
>
<Flex direction="column" gap="2">
<Grid mt="2" mb="0">
<Grid mb="0">
{integration.data.integr_values && (
<Flex
gap="4"
mb="4"
align="center"
justify="between"
className={styles.switchInline}
>
{integration.data.integr_values.available &&
Object.keys(integration.data.integr_values.available).map(
(key) => (
<IntegrationAvailability
key={key}
fieldName={key}
value={availabilityValues[key]}
onChange={handleAvailabilityChange}
/>
),
)}
<Flex align="start" justify="between">
<Flex
gap="4"
mb="4"
align="center"
justify="between"
className={styles.switchInline}
>
{integration.data.integr_values.available &&
Object.keys(integration.data.integr_values.available).map(
(key) => (
<IntegrationAvailability
key={key}
fieldName={key}
value={availabilityValues[key]}
onChange={handleAvailabilityChange}
/>
),
)}
</Flex>
<IntegrationDeletePopover
integrationName={integration.data.integr_name}
integrationConfigPath={integration.data.integr_config_path}
Expand All @@ -258,11 +260,11 @@ export const IntegrationForm: FC<IntegrationFormProps> = ({
)}
{integration.data.integr_schema.smartlinks &&
integration.data.integr_schema.smartlinks.length > 0 && (
<Flex width="100%" direction="column" gap="2" mb="6">
<Heading as="h4" size="3">
Ask AI to do it for you (experimental)
</Heading>
<Flex align="center" gap="2" mt="2" wrap="wrap">
<Flex width="100%" direction="column" gap="1" mb="6">
<Flex align="center" gap="3" mt="2" wrap="wrap">
<Heading as="h6" size="2" weight="medium">
Actions:
</Heading>
{integration.data.integr_schema.smartlinks.map(
(smartlink, index) => {
return (
Expand All @@ -281,7 +283,10 @@ export const IntegrationForm: FC<IntegrationFormProps> = ({
shouldBeDisabled={
smartlink.sl_enable_only_with_tool
? integration.data?.integr_values === null ||
!shouldIntegrationFormBeDisabled
!shouldIntegrationFormBeDisabled ||
Object.values(availabilityValues).every(
(value) => !value,
)
: false
}
/>
Expand Down Expand Up @@ -329,7 +334,10 @@ export const IntegrationForm: FC<IntegrationFormProps> = ({
size="2"
onClick={() => setAreExtraFieldsRevealed((prev) => !prev)}
mb="1"
mt="3"
mt={{
initial: "3",
xs: "0",
}}
className={styles.advancedButton}
>
{areExtraFieldsRevealed
Expand Down Expand Up @@ -401,6 +409,11 @@ export const IntegrationForm: FC<IntegrationFormProps> = ({
/>
</Flex>
)}
<Spacer />
alashchev17 marked this conversation as resolved.
Show resolved Hide resolved
</Flex>
alashchev17 marked this conversation as resolved.
Show resolved Hide resolved
);
};

const Spacer = () => {
return <Flex height="65px" />;
};
2 changes: 0 additions & 2 deletions src/components/IntegrationsView/IntegrationsHeader.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
top: 0;
left: 0;
width: 100%;
height: 80px;
border-bottom: 1px solid var(--mauve-a10);
z-index: 1000;
}

Expand Down
31 changes: 16 additions & 15 deletions src/components/IntegrationsView/IntegrationsHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ export const IntegrationsHeader: FC<IntegrationsHeaderProps> = ({
};

return (
<Flex className={styles.IntegrationsHeader} px={leftRightPadding}>
<Flex className={styles.IntegrationsHeader} px={leftRightPadding} pt="5">
<Flex align="center" justify="between" width="100%" px={leftRightPadding}>
<Flex
gap={{
initial: "3",
xs: "4",
xs: "5",
}}
align="center"
>
Expand All @@ -53,19 +53,20 @@ export const IntegrationsHeader: FC<IntegrationsHeaderProps> = ({
<ArrowLeftIcon width="16" height="16" />
</IconButton>
)}
<img
src={icon}
className={styles.IntegrationsHeaderIcon}
alt={integrationName}
/>
<Heading as="h5" size="3">
Setup{" "}
{integrationName.includes("TEMPLATE")
? integrationName.startsWith("cmdline")
? "Command Line Tool"
: "Command Line Service"
: toPascalCase(integrationName)}
</Heading>
<Flex gap="2" align="center" mt={width > 500 ? "1" : "0"}>
<img
src={icon}
className={styles.IntegrationsHeaderIcon}
alt={integrationName}
/>
<Heading as="h5" size="3">
{integrationName.includes("TEMPLATE")
? integrationName.startsWith("cmdline")
? "Command Line Tool"
: "Command Line Service"
: toPascalCase(integrationName)}
</Heading>
</Flex>
</Flex>
</Flex>
</Flex>
Expand Down
Loading
Loading