0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-11 02:59:07 +08:00
discourse/plugins/discourse-ai/lib/agents/titles_generator.rb
Rafael dos Santos Silva 2f5c074d66
FIX: AI helper title suggestions erroring on partially streamed JSON arrays (#42442)
Previously, `AiHelper::Assistant` assembled list-type results from
partial structured-output notifications, so backends that stream a JSON
array across many small deltas (e.g. a title's closing `",` and the
following whitespace as separate chunks) left a transient `nil`
placeholder in the suggestions, raising `NoMethodError: undefined method
'gsub' for nil` on every title suggestion request.

This change reads array results once from the completed structured
output after the reply finishes (streaming accumulation is kept only for
string schemas, which are the ones actually streamed to clients), and
compacts the `TitlesGenerator` example and system prompt JSON so the
model stops mimicking pretty-printed whitespace — saving roughly a third
of the completion tokens per request.
2026-08-07 14:40:18 -03:00

52 lines
2 KiB
Ruby
Vendored

# frozen_string_literal: true
module DiscourseAi
module Agents
class TitlesGenerator < Agent
def self.default_enabled
false
end
def system_prompt
<<~PROMPT.strip
I want you to act as a title generator for written pieces. I will provide you with a text,
and you will generate five titles. Please keep the title concise and under 20 words,
and ensure that the meaning is maintained. Replies will utilize the language type of the topic.
I want you to only reply the list of options and nothing else, do not write explanations.
Never ever use colons in the title. Always use sentence case, using a capital letter at
the start of the title, never start the title with a lower case letter. Proper nouns in the title
can have a capital letter, and acronyms like LLM can use capital letters. Format some titles
as questions, some as statements. Make sure to use question marks if the title is a question.
You will find the text between <input></input> XML tags.
The title suggestions should be returned in a JSON array, under the `output` key, like this:
{"output": ["suggested title #1", "suggested title #2", "suggested title #3", "suggested title #4", "suggested title #5"]}
Return only the JSON
PROMPT
end
def response_format
[{ "key" => "output", "type" => "array", "array_type" => "string" }]
end
def examples
[
[
"<input>In the labyrinth of time, a solitary horse, etched in gold by the setting sun, embarked on an infinite journey.</input>",
{
output: [
"The solitary horse",
"The horse etched in gold",
"A horse's infinite journey",
"A horse lost in time",
"A horse's last ride",
],
}.to_json,
],
]
end
end
end
end