chore: add hybrid search control (#39258)
## Description Add hybrid search control for UQI forms.  Example of usage: ``` { "isRequired": false, "configProperty": "actionConfiguration.formData.hybridSearch", "controlType": "HYBRID_SEARCH", "initialValue": { "isEnabled": true, "keywordWeight": 0.5, "semanticWeight": 0.5 } } ``` Fixes https://github.com/appsmithorg/appsmith/issues/39236 ## Automation /ok-to-test tags="@tag.Datasource" ### 🔍 Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/13324291818> > Commit: 9495722fe3224474db772890f31730becfa45d79 > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=13324291818&attempt=1" target="_blank">Cypress dashboard</a>. > Tags: `@tag.Datasource` > Spec: > <hr>Fri, 14 Feb 2025 07:52:38 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [x] No <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced a new hybrid search control in the form. Users can now easily adjust search parameters with intuitive sliders for keyword and semantic weights, along with a toggle to activate or deactivate hybrid search. - Added a new control type for hybrid search to the form control registry, enhancing the flexibility of form configurations. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
parent
23b2b9256e
commit
0e67bbc68c
78
app/client/src/components/formControls/HybridSearch.tsx
Normal file
78
app/client/src/components/formControls/HybridSearch.tsx
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
import React from "react";
|
||||||
|
import { Field, type WrappedFieldInputProps } from "redux-form";
|
||||||
|
import BaseControl from "./BaseControl";
|
||||||
|
import type { ControlProps } from "./BaseControl";
|
||||||
|
import { Slider, type SliderProps, Flex, Switch, Text } from "@appsmith/ads";
|
||||||
|
|
||||||
|
export interface HybridSearchControlProps
|
||||||
|
extends ControlProps,
|
||||||
|
Omit<SliderProps, "id" | "label"> {}
|
||||||
|
|
||||||
|
export class HybridSearchControl extends BaseControl<HybridSearchControlProps> {
|
||||||
|
render() {
|
||||||
|
const { configProperty, ...rest } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Field
|
||||||
|
component={renderHybridSearchControl}
|
||||||
|
name={configProperty}
|
||||||
|
props={{ ...rest }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getControlType(): string {
|
||||||
|
return "HYBRID_SEARCH";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderHybridSearchControl = (
|
||||||
|
props: {
|
||||||
|
input?: WrappedFieldInputProps;
|
||||||
|
} & HybridSearchControlProps,
|
||||||
|
) => {
|
||||||
|
const { input } = props;
|
||||||
|
|
||||||
|
const onSliderChange = (value: number) => {
|
||||||
|
input?.onChange({
|
||||||
|
...input?.value,
|
||||||
|
keywordWeight: value,
|
||||||
|
semanticWeight: (10 - value * 10) / 10, // Scale by 10 to avoid floating-point issues
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const onSwitchChange = (value: boolean) => {
|
||||||
|
input?.onChange({
|
||||||
|
...input?.value,
|
||||||
|
isEnabled: value,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Flex flexDirection="column" gap="spaces-4">
|
||||||
|
<Flex width="150px">
|
||||||
|
<Switch
|
||||||
|
defaultSelected={input?.value.isEnabled}
|
||||||
|
onChange={onSwitchChange}
|
||||||
|
>
|
||||||
|
Hybrid search
|
||||||
|
</Switch>
|
||||||
|
</Flex>
|
||||||
|
<Flex flexDirection="column">
|
||||||
|
<Slider
|
||||||
|
getValueLabel={() => "Semantic weight"}
|
||||||
|
isDisabled={!input?.value.isEnabled}
|
||||||
|
label="Keyword weight"
|
||||||
|
maxValue={1}
|
||||||
|
minValue={0}
|
||||||
|
onChange={onSliderChange}
|
||||||
|
step={0.1}
|
||||||
|
value={input?.value.keywordWeight}
|
||||||
|
/>
|
||||||
|
<Flex justifyContent="space-between">
|
||||||
|
<Text>{input?.value.keywordWeight}</Text>
|
||||||
|
<Text>{input?.value.semanticWeight}</Text>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -45,6 +45,7 @@ import {
|
||||||
SliderControl,
|
SliderControl,
|
||||||
type SliderControlProps,
|
type SliderControlProps,
|
||||||
} from "components/formControls/SliderControl";
|
} from "components/formControls/SliderControl";
|
||||||
|
import { HybridSearchControl } from "components/formControls/HybridSearch";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NOTE: If you are adding a component that uses FormControl
|
* NOTE: If you are adding a component that uses FormControl
|
||||||
|
|
@ -225,6 +226,11 @@ class FormControlRegistry {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
FormControlFactory.registerControlBuilder(formControlTypes.HYBRID_SEARCH, {
|
||||||
|
buildPropertyControl(controlProps: SliderControlProps): JSX.Element {
|
||||||
|
return <HybridSearchControl {...controlProps} />;
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,4 +22,5 @@ export default {
|
||||||
RAG_INTEGRATIONS: "RAG_INTEGRATIONS",
|
RAG_INTEGRATIONS: "RAG_INTEGRATIONS",
|
||||||
SLIDER: "SLIDER",
|
SLIDER: "SLIDER",
|
||||||
RAG_DOCUMENTS_SELECTOR: "RAG_DOCUMENTS_SELECTOR",
|
RAG_DOCUMENTS_SELECTOR: "RAG_DOCUMENTS_SELECTOR",
|
||||||
|
HYBRID_SEARCH: "HYBRID_SEARCH",
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user