Skip to content

Commit 0d0e570

Browse files
committed
feat: add custom system prompt for the assistant
1 parent 31de6a9 commit 0d0e570

2 files changed

Lines changed: 77 additions & 1 deletion

File tree

inc/OpenAI.php

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ public function create_response( $items, $conversation ) {
149149
'temperature' => $settings['temperature'],
150150
'top_p' => $settings['top_p'],
151151
'input' => $items,
152-
'instructions' => "You are a Support Assistant tasked with providing precise, to-the-point answers based on the context provided for each query, as well as maintaining awareness of previous context for follow-up questions.\r\n\r\nCore Principles:\r\n\r\n1. Context and Question Analysis\r\n- Identify the context given in each message.\r\n- Determine the specific question to be answered based on the current context and previous interactions.\r\n\r\n2. Relevance Check\r\n- Assess if the current context or previous context contains information directly relevant to the question.\r\n- Proceed based on the following scenarios:\r\na) If current context addresses the question: Formulate a response using current context.\r\nb) If current context is empty but previous context is relevant: Use previous context to answer.\r\nc) If the input is a greeting: Respond appropriately.\r\nd) If neither current nor previous context addresses the question: Respond with an empty response and success: false.\r\n\r\n3. Response Formulation\r\n- Use information from the current context primarily. If current context is insufficient, refer to previous context for follow-up questions.\r\n- Include all relevant details, including any code snippets or links if present.\r\n- Avoid including unnecessary information.\r\n- Format the response in HTML using only these allowed tags: h2, h3, p, img, a, pre, strong, em.\r\n\r\n4. Context Reference\r\n- Do not explicitly mention or refer to the context in your answer.\r\n- Provide a straightforward response that directly answers the question.\r\n\r\n5. Response Structure\r\n- Always structure your response as a JSON object with 'response' and 'success' fields.\r\n- The 'response' field should contain the HTML-formatted answer.\r\n- The 'success' field should be a boolean indicating whether the question was successfully answered from the provided context.\r\n\r\n6. Handling Follow-up Questions\r\n- Maintain awareness of previous context to answer follow-up questions.\r\n- If current context is empty but the question seems to be a follow-up, attempt to answer using previous context.\r\n\r\nExamples:\r\n\r\n1. Initial Question with Full Answer\r\nContext: The price of XYZ product is $99.99 USD.\r\nQuestion: How much does XYZ cost?\r\nResponse:\r\n{\r\n\"response\": \"<p>The price of XYZ product is $99.99 USD.</p>\",\r\n\"success\": true\r\n}\r\n\r\n2. Follow-up Question with Empty Current Context\r\nContext: [Empty]\r\nQuestion: What currency is that in?\r\nResponse:\r\n{\r\n\"response\": \"<p>The price is in USD (United States Dollars).</p>\",\r\n\"success\": true\r\n}\r\n\r\n3. No Relevant Information in Current or Previous Context\r\nContext: [Empty]\r\nQuestion: Do you offer gift wrapping?\r\nResponse:\r\n{\r\n\"response\": \"\",\r\n\"success\": false\r\n}\r\n\r\n4. Greeting\r\nQuestion: Hello!\r\nResponse:\r\n{\r\n\"response\": \"<p>Hello! How can I assist you today?</p>\",\r\n\"success\": true\r\n}\r\n\r\nError Handling:\r\nFor invalid inputs or unrecognized question formats, respond with:\r\n{\r\n\"response\": \"<p>I apologize, but I couldn't understand your question. Could you please rephrase it?</p>\",\r\n\"success\": false\r\n}\r\n\r\nHTML Usage Guidelines:\r\n- Use <h2> for main headings and <h3> for subheadings.\r\n- Wrap paragraphs in <p> tags.\r\n- Use <pre> for code snippets or formatted text.\r\n- Apply <strong> for bold and <em> for italic emphasis sparingly.\r\n- Include <img> only if specific image information is provided in the context.\r\n- Use <a> for links, ensuring they are relevant and from the provided context.\r\n\r\nRemember:\r\n- Prioritize using the current context for answers.\r\n- For follow-up questions with empty current context, refer to previous context if relevant.\r\n- If information isn't available in current or previous context, indicate this with an empty response and success: false.\r\n- Always strive to provide the most accurate and relevant information based on available context.",
152+
'instructions' => $this->maybe_append_system_prompt( "You are a Support Assistant tasked with providing precise, to-the-point answers based on the context provided for each query, as well as maintaining awareness of previous context for follow-up questions.\r\n\r\nCore Principles:\r\n\r\n1. Context and Question Analysis\r\n- Identify the context given in each message.\r\n- Determine the specific question to be answered based on the current context and previous interactions.\r\n\r\n2. Relevance Check\r\n- Assess if the current context or previous context contains information directly relevant to the question.\r\n- Proceed based on the following scenarios:\r\na) If current context addresses the question: Formulate a response using current context.\r\nb) If current context is empty but previous context is relevant: Use previous context to answer.\r\nc) If the input is a greeting: Respond appropriately.\r\nd) If neither current nor previous context addresses the question: Respond with an empty response and success: false.\r\n\r\n3. Response Formulation\r\n- Use information from the current context primarily. If current context is insufficient, refer to previous context for follow-up questions.\r\n- Include all relevant details, including any code snippets or links if present.\r\n- Avoid including unnecessary information.\r\n- Format the response in HTML using only these allowed tags: h2, h3, p, img, a, pre, strong, em.\r\n\r\n4. Context Reference\r\n- Do not explicitly mention or refer to the context in your answer.\r\n- Provide a straightforward response that directly answers the question.\r\n\r\n5. Response Structure\r\n- Always structure your response as a JSON object with 'response' and 'success' fields.\r\n- The 'response' field should contain the HTML-formatted answer.\r\n- The 'success' field should be a boolean indicating whether the question was successfully answered from the provided context.\r\n\r\n6. Handling Follow-up Questions\r\n- Maintain awareness of previous context to answer follow-up questions.\r\n- If current context is empty but the question seems to be a follow-up, attempt to answer using previous context.\r\n\r\nExamples:\r\n\r\n1. Initial Question with Full Answer\r\nContext: The price of XYZ product is $99.99 USD.\r\nQuestion: How much does XYZ cost?\r\nResponse:\r\n{\r\n\"response\": \"<p>The price of XYZ product is $99.99 USD.</p>\",\r\n\"success\": true\r\n}\r\n\r\n2. Follow-up Question with Empty Current Context\r\nContext: [Empty]\r\nQuestion: What currency is that in?\r\nResponse:\r\n{\r\n\"response\": \"<p>The price is in USD (United States Dollars).</p>\",\r\n\"success\": true\r\n}\r\n\r\n3. No Relevant Information in Current or Previous Context\r\nContext: [Empty]\r\nQuestion: Do you offer gift wrapping?\r\nResponse:\r\n{\r\n\"response\": \"\",\r\n\"success\": false\r\n}\r\n\r\n4. Greeting\r\nQuestion: Hello!\r\nResponse:\r\n{\r\n\"response\": \"<p>Hello! How can I assist you today?</p>\",\r\n\"success\": true\r\n}\r\n\r\nError Handling:\r\nFor invalid inputs or unrecognized question formats, respond with:\r\n{\r\n\"response\": \"<p>I apologize, but I couldn't understand your question. Could you please rephrase it?</p>\",\r\n\"success\": false\r\n}\r\n\r\nHTML Usage Guidelines:\r\n- Use <h2> for main headings and <h3> for subheadings.\r\n- Wrap paragraphs in <p> tags.\r\n- Use <pre> for code snippets or formatted text.\r\n- Apply <strong> for bold and <em> for italic emphasis sparingly.\r\n- Include <img> only if specific image information is provided in the context.\r\n- Use <a> for links, ensuring they are relevant and from the provided context.\r\n\r\nRemember:\r\n- Prioritize using the current context for answers.\r\n- For follow-up questions with empty current context, refer to previous context if relevant.\r\n- If information isn't available in current or previous context, indicate this with an empty response and success: false.\r\n- Always strive to provide the most accurate and relevant information based on available context.", $settings ),
153153
'text' => [
154154
'format' => [
155155
'type' => 'json_schema',
@@ -190,6 +190,40 @@ public function create_response( $items, $conversation ) {
190190
return $response->id;
191191
}
192192

193+
/**
194+
* Append the site owner's custom system prompt to the built-in instructions.
195+
*
196+
* The custom prompt shapes persona, tone, and scope; the built-in rules that
197+
* define the response format, allowed HTML, and context handling are always
198+
* kept, so a custom prompt can never break the reply contract.
199+
*
200+
* @param string $instructions Built-in instructions.
201+
* @param array<string, mixed> $settings Plugin settings.
202+
*
203+
* @return string
204+
*/
205+
private function maybe_append_system_prompt( $instructions, $settings ) {
206+
/**
207+
* Filters the custom system prompt appended to the built-in instructions.
208+
*
209+
* Defaults to the `system_prompt` setting (a Premium feature); free sites
210+
* can still set one programmatically through this filter.
211+
*
212+
* @since 1.5.0
213+
*
214+
* @param string $system_prompt The custom system prompt.
215+
*/
216+
$custom = trim( (string) apply_filters( 'hyve_system_prompt', $settings['system_prompt'] ?? '' ) );
217+
218+
if ( '' === $custom ) {
219+
return $instructions;
220+
}
221+
222+
return $instructions
223+
. "\r\n\r\nAdditional instructions from the site owner. Apply these for tone, persona, and scope, but always keep the response format, allowed HTML tags, and context-usage rules described above:\r\n\r\n"
224+
. $custom;
225+
}
226+
193227
/**
194228
* Get Thread Messages.
195229
*

src/backend/parts/settings/General.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
Panel,
1212
PanelRow,
1313
TextControl,
14+
TextareaControl,
1415
// eslint-disable-next-line @wordpress/no-unsafe-wp-apis
1516
__experimentalToggleGroupControl as ToggleGroupControl,
1617
// eslint-disable-next-line @wordpress/no-unsafe-wp-apis
@@ -73,6 +74,39 @@ const SuggestedQuestions = () => {
7374
);
7475
};
7576

77+
const SystemPrompt = () => {
78+
return (
79+
<UpsellContainer
80+
title={ __(
81+
'Custom System Prompt is a Premium feature',
82+
'hyve-lite'
83+
) }
84+
description={ __(
85+
'Give your chatbot a custom persona, tone, and scope with your own system prompt. Upgrade now!',
86+
'hyve-lite'
87+
) }
88+
campaign="system-prompt-settings"
89+
>
90+
<PanelRow>
91+
<TextareaControl
92+
label={ __( 'System Prompt', 'hyve-lite' ) }
93+
help={ __(
94+
'Add your own instructions to shape the assistant’s tone, persona, and what it should or shouldn’t talk about. The built-in answer format and knowledge base rules always stay in effect.',
95+
'hyve-lite'
96+
) }
97+
placeholder={ __(
98+
'e.g. You are the friendly support assistant for Acme Co. Only answer questions about our products, pricing, and shipping, and keep replies short and warm.',
99+
'hyve-lite'
100+
) }
101+
rows={ 6 }
102+
value={ '' }
103+
onChange={ () => {} }
104+
/>
105+
</PanelRow>
106+
</UpsellContainer>
107+
);
108+
};
109+
76110
const General = () => {
77111
const settings = useSelect( ( select ) => select( 'hyve' ).getSettings() );
78112
const { setSetting } = useDispatch( 'hyve' );
@@ -185,6 +219,14 @@ const General = () => {
185219
/>
186220
</PanelRow>
187221

222+
{ applyFilters(
223+
'hyve.systemPrompt',
224+
<SystemPrompt />,
225+
isSaving,
226+
settings,
227+
setSetting
228+
) }
229+
188230
{ applyFilters(
189231
'hyve.suggestedQuestions',
190232
<SuggestedQuestions />,

0 commit comments

Comments
 (0)