Skip to content

Commit 1dd058c

Browse files
Add option of hiding think tag from response
Signed-off-by: Leslie Lazzarino <leslie.lazzarino@gmail.com>
1 parent 039ecec commit 1dd058c

4 files changed

Lines changed: 43 additions & 6 deletions

File tree

public/options.html

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,19 @@ <h2>Context</h2>
151151
</div>
152152
</div>
153153

154+
<div class="settings-section">
155+
<h2>Response</h2>
156+
<div class="form-group">
157+
<input type="checkbox" id="strip_think_tag" name="strip think tag" />
158+
<label for="strip_think_tag" style="display: inline-block; margin-left: 5px">
159+
Remove &lt;think&gt; tag and its content from the response
160+
<sup title="When enabled, any &lt;think&gt;...&lt;/think&gt; block produced by reasoning models will be stripped from the response before it is inserted into the composer.">
161+
&#8505;&#65039;
162+
</sup>
163+
</label>
164+
</div>
165+
</div>
166+
154167
<div class="settings-section">
155168
<h2>Model settings</h2>
156169
<div class="form-group">

src/llmButtonClickHandling.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -168,13 +168,19 @@ async function handleComposeSuccessResponse(tabId: number, response: LlmTextComp
168168
}
169169

170170
async function getCleanedUpGeneratedEmail(response: LlmTextCompletionResponse, signature: string | undefined) {
171-
const responseWithoutSignature = signature
172-
? response.choices[0].message.content.replace(signature, "")
173-
: response.choices[0].message.content;
174-
171+
const options = await getPluginOptions();
172+
let content = response.choices[0].message.content;
173+
if (options.strip_think_tag) {
174+
content = stripThinkTag(content);
175+
}
176+
const responseWithoutSignature = signature ? content.replace(signature, "") : content;
175177
return responseWithoutSignature.replace(/^\s*/, "");
176178
}
177179

180+
export function stripThinkTag(text: string): string {
181+
return text.replace(/<think>[\s\S]*?<\/think>/gi, "");
182+
}
183+
178184
function handleLlmErrorResponse(response: TgiErrorResponse) {
179185
throw Error(`LLM responded with an error: ${response.error.message}`);
180186
}
@@ -188,11 +194,18 @@ export async function summarize(tabId: number, originalConversation?: string): P
188194
const requestStatus = allRequestsStatus.getRequestStatus(tabId);
189195
const response = await sendContentToLlm(messages, requestStatus.abortController.signal);
190196
if (isLlmTextCompletionResponse(response)) {
197+
const options = await getPluginOptions();
198+
let content = (response as LlmTextCompletionResponse).choices[0].message.content;
199+
if (options.strip_think_tag) {
200+
content = stripThinkTag(content);
201+
}
191202
await browser.compose.setComposeDetails(tabId, {
192-
plainTextBody: `${response.choices[0].message.content}\n\n\n\n${originalConversation}`,
203+
plainTextBody: `${content}\n\n\n\n${originalConversation}`,
193204
});
194205
} else {
195-
throw Error(`LLM while attempting to summarize responded with an error: ${response.error.message}`);
206+
throw Error(
207+
`LLM while attempting to summarize responded with an error: ${(response as TgiErrorResponse).error.message}`,
208+
);
196209
}
197210
}
198211

src/options.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ document.querySelector("#api_token")?.addEventListener("change", updateApiToken)
88
document.querySelector("#timeout")?.addEventListener("change", updateTimeout);
99
document.querySelector("#llm_context")?.addEventListener("change", updateLlmContext);
1010
document.querySelector("#use_last_mails")?.addEventListener("change", updateUseLastMails);
11+
document.querySelector("#strip_think_tag")?.addEventListener("change", updateStripThinkTag);
1112
document.querySelector("#context_window")?.addEventListener("change", updateContextWindow);
1213
document.querySelector("#other_options")?.addEventListener("change", updateOtherOptions);
1314

@@ -53,6 +54,13 @@ async function updateUseLastMails(event: Event) {
5354
await browser.storage.sync.set({ options });
5455
}
5556

57+
async function updateStripThinkTag(event: Event) {
58+
const stripThinkTagInput = event.target as HTMLInputElement;
59+
const options = await getPluginOptions();
60+
options.strip_think_tag = stripThinkTagInput.checked;
61+
await browser.storage.sync.set({ options });
62+
}
63+
5664
async function updateContextWindow(event: Event) {
5765
const contextWindowInput = event.target as HTMLInputElement;
5866
const options = await getPluginOptions();
@@ -77,6 +85,7 @@ export async function restoreOptions(): Promise<void> {
7785
getInputElement("#timeout").value = options.timeout ? `${options.timeout / 1000}` : "";
7886
getInputElement("#context_window").value = `${options.context_window}`;
7987
getInputElement("#use_last_mails").checked = options.include_recent_mails;
88+
getInputElement("#strip_think_tag").checked = options.strip_think_tag;
8089
getInputElement("#other_options").value = JSON.stringify(options.params, null, 2);
8190
getInputElement("#llm_context").value = options.llmContext;
8291
}

src/optionsParams.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export interface Options {
2121
api_token?: string;
2222
context_window: number;
2323
include_recent_mails: boolean;
24+
strip_think_tag: boolean;
2425
params: LlmParameters;
2526
llmContext: string;
2627
timeout?: number; // Timeout in milliseconds, undefined means no timeout
@@ -32,6 +33,7 @@ export const DEFAULT_OPTIONS: Options = {
3233
model: "",
3334
context_window: 4096,
3435
params: DEFAULT_PARAMS,
36+
strip_think_tag: true,
3537
llmContext:
3638
"I need to write an email.\n" +
3739
"The email should be concise.\n" +

0 commit comments

Comments
 (0)