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

Experimental: styled prompt #88

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,12 @@ summary_num_results: 10
# If you are a Vectara scale customer you can use custom prompts.
# This field names a custom prompt, otherwise it uses the default for the account.
summary_prompt_name: vectara-summary-ext-v1.2.0

# "true" if you want to enable prompt styling, any other value considered false
# prompt styling enables customized prompt for style of response
# This is only possible with the Vectara Scale plan.
summary_styled_prompt: "false"

```

#### Hybrid Search (optional)
Expand Down
3 changes: 3 additions & 0 deletions config/hackernews-search/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@ summary_default_language: "eng"
summary_num_sentences: 3
summary_num_results: 7

summary_prompt_name: vectara-summary-ext-v1.4.0
#summary_prompt_name: vectara-summary-ext-v1.2.0
ofermend marked this conversation as resolved.
Show resolved Hide resolved

enable_source_filters: False

2 changes: 1 addition & 1 deletion config/hackernews-search/queries.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"questions": [
"what's new with GPT4?",
"should we stop working on AI?",
"use cases for LLM",
"What did Microsoft do?",
"Will AI kill humanity?"
]
}
6 changes: 5 additions & 1 deletion docker/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,11 @@ app.post("/config", (req, res) => {

// Summary
summary_default_language,
summary_default_style,
summary_num_results,
summary_num_sentences,
summary_prompt_name,
summary_styled_prompt,

// rerank
rerank,
Expand Down Expand Up @@ -125,10 +127,12 @@ app.post("/config", (req, res) => {

// summary
summary_default_language,
summary_default_style,
summary_num_results,
summary_num_sentences,
summary_prompt_name,

summary_styled_prompt,

// hybrid search
hybrid_search_num_words,
hybrid_search_lambda_long,
Expand Down
4 changes: 4 additions & 0 deletions server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,11 @@ app.post("/config", (req, res) => {

// summary
summary_default_language,
summary_default_style,
summary_num_results,
summary_num_sentences,
summary_prompt_name,
summary_styled_prompt,

// hybrid search
hybrid_search_num_words,
Expand Down Expand Up @@ -124,9 +126,11 @@ app.post("/config", (req, res) => {

// summary
summary_default_language,
summary_default_style,
summary_num_results,
summary_num_sentences,
summary_prompt_name,
summary_styled_prompt,

// hybrid search
hybrid_search_num_words,
Expand Down
10 changes: 10 additions & 0 deletions src/contexts/ConfigurationContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,11 @@ interface Config {

// Summary
config_summary_default_language?: string;
config_summary_default_style?: string;
config_summary_num_results?: number;
config_summary_num_sentences?: number;
config_summary_prompt_name?: string;
config_summary_styled_prompt?: string;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a boolean, since it's a flag:

config_summary_styled_prompt?: boolean;

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is actually a string in all our configs (e.g in "mmr" and "enable_source_filters"). Why would it be different here? In all those cases, we'd be using isTrue(X) as above.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, my mistake!


// hybrid search
config_hybrid_search_num_words?: number;
Expand Down Expand Up @@ -118,9 +120,11 @@ type Filters = {

type Summary = {
defaultLanguage: string;
defaultStyle: string;
summaryNumResults: number;
summaryNumSentences: number;
summaryPromptName: string;
summaryStyledPrompt: string;
};

type SearchHeader = {
Expand Down Expand Up @@ -266,9 +270,11 @@ export const ConfigContextProvider = ({ children }: Props) => {

const [summary, setSummary] = useState<Summary>({
defaultLanguage: "auto",
defaultStyle: "default",
summaryNumResults: 7,
summaryNumSentences: 3,
summaryPromptName: "vectara-summary-ext-v1.2.0",
summaryStyledPrompt: "false",
});

useEffect(() => {
Expand Down Expand Up @@ -364,9 +370,11 @@ export const ConfigContextProvider = ({ children }: Props) => {

// Summary
config_summary_default_language,
config_summary_default_style,
config_summary_num_results,
config_summary_num_sentences,
config_summary_prompt_name,
config_summary_styled_prompt,
} = config;

setUxMode(config_ux ?? "summary");
Expand Down Expand Up @@ -431,10 +439,12 @@ export const ConfigContextProvider = ({ children }: Props) => {
config_summary_default_language as SummaryLanguage,
"auto"
),
defaultStyle: config_summary_default_style ?? "default",
ofermend marked this conversation as resolved.
Show resolved Hide resolved
summaryNumResults: config_summary_num_results ?? 7,
summaryNumSentences: config_summary_num_sentences ?? 3,
summaryPromptName:
config_summary_prompt_name ?? "vectara-summary-ext-v1.2.0",
summaryStyledPrompt: config_summary_styled_prompt ?? "false",
ofermend marked this conversation as resolved.
Show resolved Hide resolved
});

setSearchHeader({
Expand Down
29 changes: 27 additions & 2 deletions src/contexts/SearchContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
SummaryLanguage,
SearchError,
} from "../views/search/types";
import { SummaryStyle } from "../views/search/styles";
import { useConfigContext } from "./ConfigurationContext";
import { sendSearchRequest } from "./sendSearchRequest";
import {
Expand All @@ -33,11 +34,13 @@ interface SearchContextType {
value,
filter,
language,
style,
isPersistable,
}: {
value?: string;
filter?: string;
language?: SummaryLanguage;
style?: SummaryStyle;
isPersistable?: boolean;
}) => void;
reset: () => void;
Expand All @@ -50,9 +53,11 @@ interface SearchContextType {
summarizationResponse: SearchResponse | undefined;
summaryTime: number;
language: SummaryLanguage;
style: SummaryStyle;
summaryNumResults: number;
summaryNumSentences: number;
summaryPromptName: string;
summaryStyledPrompt: string;
history: HistoryItem[];
clearHistory: () => void;
searchResultsRef: React.MutableRefObject<HTMLElement[] | null[]>;
Expand Down Expand Up @@ -84,8 +89,9 @@ export const SearchContextProvider = ({ children }: Props) => {

const [searchParams, setSearchParams] = useSearchParams();

// Language
// Language & Style
const [languageValue, setLanguageValue] = useState<SummaryLanguage>();
const [styleValue, setStyleValue] = useState<SummaryStyle>();

// History
const [history, setHistory] = useState<HistoryItem[]>([]);
Expand Down Expand Up @@ -131,6 +137,9 @@ export const SearchContextProvider = ({ children }: Props) => {
language: getQueryParam(urlParams, "language") as
| SummaryLanguage
| undefined,
style: getQueryParam(urlParams, "style") as
ofermend marked this conversation as resolved.
Show resolved Hide resolved
| SummaryStyle
| undefined,
isPersistable: false,
});
// eslint-disable-next-line react-hooks/exhaustive-deps
Expand Down Expand Up @@ -174,22 +183,28 @@ export const SearchContextProvider = ({ children }: Props) => {
const getLanguage = (): SummaryLanguage =>
(languageValue ?? summary.defaultLanguage) as SummaryLanguage;

const getStyle = (): SummaryStyle =>
(styleValue ?? summary.defaultStyle) as SummaryStyle;

const onSearch = async ({
value = searchValue,
filter = filterValue,
language = getLanguage(),
style = getStyle(),
isPersistable = true,
}: {
value?: string;
filter?: string;
language?: SummaryLanguage;
style?: SummaryStyle;
isPersistable?: boolean;
}) => {
const searchId = ++searchCount;

setSearchValue(value);
setFilterValue(filter);
setLanguageValue(language);
setStyleValue(style);

if (value?.trim()) {
// Save to history.
Expand Down Expand Up @@ -255,6 +270,14 @@ export const SearchContextProvider = ({ children }: Props) => {
setSearchResponse(undefined);
}

// Scale customers can use custom prompts.
// This feature demonstrates a specific way to do thi
// 1. Talk to Vectara sales about joining a Scale plan
// 2. Define a series of prompt names, all ending with "_<style>"
// 3. Update "styles.ts" to match these styles
// 4. Update "config.json" to include the correct base prompt name
const styledPromptName = summary.summaryPromptName + '_' + style;

// Second call - search and summarize (if summary is enabled); this may take a while to return results
if (isSummaryEnabled) {
if (initialSearchResponse.response.length > 0) {
Expand All @@ -270,7 +293,7 @@ export const SearchContextProvider = ({ children }: Props) => {
rerankDiversityBias: rerank.diversityBias,
summaryNumResults: summary.summaryNumResults,
summaryNumSentences: summary.summaryNumSentences,
summaryPromptName: summary.summaryPromptName,
summaryPromptName: styledPromptName,
hybridNumWords: hybrid.numWords,
hybridLambdaLong: hybrid.lambdaLong,
hybridLambdaShort: hybrid.lambdaShort,
Expand Down Expand Up @@ -339,9 +362,11 @@ export const SearchContextProvider = ({ children }: Props) => {
summarizationResponse,
summaryTime,
language: getLanguage(),
style: getStyle(),
summaryNumResults: summary.summaryNumResults,
summaryNumSentences: summary.summaryNumSentences,
summaryPromptName: summary.summaryPromptName,
summaryStyledPrompt: summary.summaryStyledPrompt,
history,
clearHistory,
searchResultsRef,
Expand Down
2 changes: 2 additions & 0 deletions src/contexts/sendSearchRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type Config = {
summaryNumResults?: number;
summaryNumSentences?: number;
summaryPromptName?: string;
summaryStyledPrompt?: string;
customerId: string;
corpusId: string;
endpoint: string;
Expand All @@ -38,6 +39,7 @@ export const sendSearchRequest = async ({
summaryNumResults,
summaryNumSentences,
summaryPromptName,
summaryStyledPrompt,
customerId,
corpusId,
endpoint,
Expand Down
1 change: 1 addition & 0 deletions src/ui/components/summary/_index.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.vuiSummary {
font-size: $fontSizeMedium;
white-space: pre-line;
}

.vuiSummaryCitation {
Expand Down
51 changes: 48 additions & 3 deletions src/views/search/controls/OptionsDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,35 @@ import {
VuiTitle,
} from "../../../ui";
import { SUMMARY_LANGUAGES, SummaryLanguage, humanizeLanguage } from "../types";
import { SUMMARY_STYLES, SummaryStyle, humanizeStyle } from "../styles";
import { useConfigContext } from "../../../contexts/ConfigurationContext";

const languageOptions = SUMMARY_LANGUAGES.map((code) => ({
value: code,
label: humanizeLanguage(code),
}));

const styleOptions = SUMMARY_STYLES.map((code) => ({
value: code,
label: humanizeStyle(code),
}));

type Props = {
isOpen: boolean;
onClose: () => void;
};

export const OptionsDrawer = ({ isOpen, onClose }: Props) => {
const { uxMode, setUxMode } = useConfigContext();
const { language, onSearch } = useSearchContext();
const { uxMode, setUxMode, summary } = useConfigContext();
const { language, style, onSearch } = useSearchContext();

const [newUxMode, setNewUxMode] = useState(uxMode);
const [isLanguageMenuOpen, seIisLanguageMenuOpen] = useState(false);
const [newLanguage, setNewLanguage] = useState<SummaryLanguage>(language);

const [isStyleMenuOpen, seIisStyleMenuOpen] = useState(false);
const [newStyle, setNewStyle] = useState<SummaryStyle>(style);

return (
<VuiDrawer
isOpen={isOpen}
Expand Down Expand Up @@ -93,6 +102,41 @@ export const OptionsDrawer = ({ isOpen, onClose }: Props) => {

<VuiSpacer size="m" />

{ summary.summaryStyledPrompt === "true" ? (
<>

<VuiLabel>Summary Style</VuiLabel>

<VuiSpacer size="xs" />

<VuiText size="xs">
<VuiTextColor color="subdued">
<p>Summaries will be created in this style or format.</p>
</VuiTextColor>
</VuiText>

<VuiSpacer size="xs" />

<VuiSearchSelect
isOpen={isStyleMenuOpen}
setIsOpen={seIisStyleMenuOpen}
onSelect={(value: string[]) => {
setNewStyle(value[0] as SummaryStyle);
}}
selected={[newStyle]}
options={styleOptions}
isMultiSelect={false}
>
<VuiButtonSecondary color="neutral" size="m">
{newStyle}
</VuiButtonSecondary>
</VuiSearchSelect>

<VuiSpacer size="m" />
</>
) : null
}

<VuiFormGroup
label="UX mode"
labelFor="uxModeSelect"
Expand Down Expand Up @@ -132,9 +176,10 @@ export const OptionsDrawer = ({ isOpen, onClose }: Props) => {
<VuiButtonPrimary
color="primary"
onClick={() => {
if (newLanguage !== language) {
if (newLanguage !== language || newStyle !== style) {
onSearch({
language: newLanguage as SummaryLanguage,
style: newStyle as SummaryStyle,
});
}

Expand Down
Loading