response_postprocessor
Central response postprocessing pipeline.
Transforms raw LLM output into clean, Discord-friendly text before it is sent to any platform adapter. The pipeline runs every step in order:
Extract and strip
<thought>/<thinking>/💡thought…</font>tagsWrap raw (undelimited) LaTeX in display math delimiters
Convert LaTeX to Discord-friendly Unicode
Convert Markdown tables to Unicode box-drawing tables
Strip echoed message-metadata patterns
Filter backticks around Discord mentions
Strip orphaned XML-style tags (e.g.
</xai:function_call>)Strip hallucinated tool-call JSON /
<tool_call>tagsReplace special tokens
Strip any leading preamble text before the first
[
- async response_postprocessor.llm_filter_response(response_text, system_prompt=None, api_key=None)[source]
Run an LLM-based filter to detect undesirable response behaviors.
Sends the response to Gemini Flash via the local proxy. The model answers YES (undesirable) or NO (acceptable). Reasoning is disabled; any extra text is stripped to extract the verdict.
- Parameters:
response_text (
str) – The original LLM response to evaluate.system_prompt (
str|None) – Custom system prompt for the classifier. If None, uses a default that targets overrefusal, nonsense, self-repeat.api_key (
str|None) – OpenRouter API key. If None, uses OPENROUTER_API_KEY or API_KEY env, or config.api_key.
- Return type:
- Returns:
True if the response is undesirable (filter it out), False if acceptable or on error (fail-open).
- response_postprocessor.extract_status_tags(text)[source]
Extract
<dstatus>tags and return(cleaned_text, last_status).If multiple tags are present the last one wins (matches old codebase behaviour). The tags are stripped from the output text.
- response_postprocessor.postprocess_response(text)[source]
Run the full postprocessing pipeline on text and return the result.
Returns an empty string if the input is
Noneor whitespace-only after processing.
- response_postprocessor.postprocess_intermediate_response(text)[source]
Lightweight cleanup for assistant text emitted during tool-use rounds.
Skips LaTeX/table conversion and
strip_leading_preambleso short user-visible status lines (e.g. “Checking that now…”) are not dropped when the model has not yet emitted a full formatted reply header.
- response_postprocessor.extract_and_strip_thoughts(text)[source]
Remove
<thought>,<thinking>, and💡thought…</font>blocks.Returns
(cleaned_text, list_of_thought_strings).
- response_postprocessor.wrap_raw_latex(text)[source]
Detect raw (undelimited) LaTeX and wrap it in
$$...$$.
- response_postprocessor.convert_markdown_tables_to_unicode(text)[source]
Convert Markdown tables to Unicode box-drawing character tables.
- response_postprocessor.strip_message_metadata(text)[source]
Remove
[timestamp] User (ID) [Message ID: ID] :patterns.
- response_postprocessor.strip_orphaned_tags(text)[source]
Remove orphaned
</xai:function_call>tags and similar.
- response_postprocessor.strip_tool_call_artifacts(text)[source]
Remove hallucinated tool-call tags and JSON blobs from the output.
- response_postprocessor.replace_special_tokens(text)[source]
Replace known special tokens with their intended characters.
- response_postprocessor.strip_leading_preamble(text)[source]
Strip leaked thought/preamble text before the status header.
When the model’s
<thinking>close tag is malformed the regex-based strippers miss it, leaving residual thought content at the start of the response. This safety net removes everything that precedes the header, identified by[``` (backtick immediately after the opening bracket, which is the model-name header format[`model` :: ...]), or by[<code>(HTML header format used on Matrix).Plain
[characters used in markdown links, arrays, or prose are left untouched.