Commit Graph

404 Commits

Author SHA1 Message Date
Roman Rizzi aef84bc5bb
FEATURE: Examples support for personas. (#1334)
Examples simulate previous interactions with an LLM and come
right after the system prompt. This helps grounding the model and
producing better responses.
2025-05-13 10:06:16 -03:00
Sam cf45e6884c
FIX: persona triage should be logged to automation (#1326)
We were logging persona triage as "bot" in logs, causing some
confusions around real world usage

This amends it so we log usage to "automation - AUTOMATION NAME"
2025-05-08 12:51:36 +10:00
Sam 2a62658248
FEATURE: support configurable thinking tokens for Gemini (#1322) 2025-05-08 07:39:50 +10:00
Roman Rizzi c0a2d4c935
DEV: Use structured responses for summaries (#1252)
* DEV: Use structured responses for summaries

* Fix system specs

* Make response_format a first class citizen and update endpoints to support it

* Response format can be specified in the persona

* lint

* switch to jsonb and make column nullable

* Reify structured output chunks. Move JSON parsing to the depths of Completion

* Switch to JsonStreamingTracker for partial JSON parsing
2025-05-06 10:09:39 -03:00
Rafael dos Santos Silva 4eac377987
DEV: Zero delays on fake endpoint used in tests (#1311) 2025-05-05 17:47:32 -03:00
Roman Rizzi 48305dc7d3
FIX: resource_url replacemente in Persona's system prompt (#1310) 2025-05-05 11:41:04 -03:00
Sam a6fa619c31
FEATURE: enforce jpg/png for all images (#1309)
This ensures webp / gif are converted to png prior to sending
to LLMs given webp and gif are not evenly supported.

png/jpg is universally supported and are the only supported format.

longer term we need to add support for audio/video/pdf which is supported by some models.

* more specs
2025-05-05 17:46:37 +10:00
Sam 9196546f6f
FIX: better LLM feedback for image generation failures (#1306)
* FIX: handle error conditions when generating images gracefully

* FIX: also handle error for edit_image

* Update lib/inference/open_ai_image_generator.rb

Co-authored-by: Krzysztof Kotlarek <kotlarek.krzysztof@gmail.com>

* lint

---------

Co-authored-by: Krzysztof Kotlarek <kotlarek.krzysztof@gmail.com>
2025-05-01 19:25:38 +10:00
Sam 491dac298f
FIX: system persona state leaking between sites (#1304)
System personas leaned on reused classes, this was a problem
in a multisite environement cause state, such as "enabled"
ended up being reused between sites.

New implementation ensures state is pristine between sites in
a multisite

* more handling for new superclass story

* small oversight, display name should be used for display
2025-05-01 13:24:53 +10:00
Sam 7dc3c30fa4
FEATURE: correctly decorate AI bots (#1300)
AI bots come in 2 flavors

1. An LLM and LLM user, in this case we should decorate posts with persona name
2. A Persona user, in this case, in PMs we decorate with LLM name

(2) is a significant improvement, cause previously when creating a conversation
you could not tell which LLM you were talking to by simply looking at the post, you would
have to scroll to the top of the page.

* lint

* translation missing
2025-04-30 16:36:38 +10:00
Sam 17f04c76d8
FEATURE: add OpenAI image generation and editing capabilities (#1293)
This commit enhances the AI image generation functionality by adding support for:

1. OpenAI's GPT-based image generation model (gpt-image-1)
2. Image editing capabilities through the OpenAI API
3. A new "Designer" persona specialized in image generation and editing
4. Two new AI tools: CreateImage and EditImage

Technical changes include:
- Renaming `ai_openai_dall_e_3_url` to `ai_openai_image_generation_url` with a migration
- Adding `ai_openai_image_edit_url` setting for the image edit API endpoint
- Refactoring image generation code to handle both DALL-E and the newer GPT models
- Supporting multipart/form-data for image editing requests

* wild guess but maybe quantization is breaking the test sometimes

this increases distance

* Update lib/personas/designer.rb

Co-authored-by: Alan Guo Xiang Tan <gxtan1990@gmail.com>

* simplify and de-flake code

* fix, in chat we need enough context so we know exactly what uploads a user uploaded.

* Update lib/personas/tools/edit_image.rb

Co-authored-by: Alan Guo Xiang Tan <gxtan1990@gmail.com>

* cleanup downloaded files right away

* fix implementation

---------

Co-authored-by: Alan Guo Xiang Tan <gxtan1990@gmail.com>
2025-04-29 17:38:54 +10:00
Mark VanLandingham b7b9179bc8
FEATURE: Allow for persona & llm selection in bot conversations page (#1276) 2025-04-24 11:17:24 -05:00
Sam 65718f6dbe
FIX: eat all leading spaces llms provide when they stream them (#1280)
* FIX: eat all leading spaces llms provide when they stream them

* improve so we don't stop replying...
2025-04-24 22:07:26 +10:00
Sam 0f34ce999f
FIX: omit thinking tokens from chat (#1264)
* FIX: omit thinking tokens from chat

Thinking tokens cause a lot of confusion in chat, get rid of them

* also catch partial tool just in case
2025-04-15 17:13:20 +10:00
Sam 274a54a324
FEATURE: Update model names and specs (#1262)
* FEATURE: Update model names and specs

- not a bug, but made it explicit that tools and thinking are not a chat thing
- updated all models to latest in presets (Gemini and OpenAI)

* allow larger context windows
2025-04-15 16:33:44 +10:00
Sam 38b492529f
FEATURE: improve context management (#1260)
1. Add age of post to topic context (1 month ago, 1 year ago, etc)
2. Refactor code for simplicity
3. Fix handling of post context in DMs which was not using new handling of uploads
2025-04-14 21:45:48 +10:00
Sam 67e3a610cb
FIX: invalid context construction for responders (#1257)
Previous to this fix we assumed the name field contained usernames
when in fact it was stored in the id field.

This fixes the context contruction and also adds some basic user
information to the context to assist responders in understanding
the cast of chars
2025-04-12 08:15:31 +10:00
Sam e15984029d
FEATURE: allow tools to amend personas (#1250)
Add API methods to AI tools for reading and updating personas, enabling
more flexible AI workflows. This allows custom tools to:

- Fetch persona information through discourse.getPersona()
- Update personas with modified settings via discourse.updatePersona()
- Also update using persona.update()

These APIs enable new use cases like "trainable" moderation bots, where
users with appropriate permissions can set and refine moderation rules
through direct chat interactions, without needing admin panel access.

Also adds a special API scope which allows people to lean on API
for similar actions

Additionally adds a rather powerful hidden feature can allow custom tools
to inject content into the context unconditionally it can be used for memory and similar features
2025-04-09 15:48:25 +10:00
Roman Rizzi f9d641dd3a
FIX: Restore gists previous group access behavior. (#1247)
Previously, allowing "everyone" to access gists meant anons would see them too.
With the move to Personas, we used "[]" to reflect that.

With discourse/discourse#32199 adding the "everyone" option to the personas-allowed
groups, we are switching back to the original behavior.
Leaving allowed groups empty should always mean nobody can use the feature.
2025-04-07 12:04:30 -03:00
Sam ed907dd004
FEATURE: allow to send LLM reports to groups (#1246)
* FEATURE: allow to send LLM reports to groups

* spec regression
2025-04-07 15:31:30 +10:00
Roman Rizzi fccd072f44
DEV: Don't use delays for streaming summaries. (#1244)
We started used a callback as a buffer in FoldContent, so the Fake endpoint is attempting
to emulate delays in the streaming. However, we don't care about that in these specs.
2025-04-02 13:38:15 -03:00
Roman Rizzi 0d60aca6ef
FEATURE: Personas powered summaries. (#1232)
* REFACTOR: Move personas into it's own module.

* WIP: Use personas for summarization

* Prioritize persona default LLM or fallback to newest one

* Simplify summarization strategy

* Keep ai_sumarization_model as a fallback
2025-04-02 12:54:47 -03:00
Sam 8b573fe743
FIX: maintain newest uploads correctly when constructing context (#1242) 2025-04-02 10:09:38 -03:00
Roman Rizzi 30242a27e6
REFACTOR: Move personas into its own module. (#1233)
This change moves all the personas code into its own module. We want to treat them as a building block features can built on top of, same as `Completions::Llm`.

The code to title a message was moved from `Bot` to `Playground`.
2025-03-31 14:42:33 -03:00
Sam 5b6d39a206
FEATURE: flexible image handling within messages (#1214)
* DEV: refactor bot internals

This introduces a proper object for bot context, this makes
it simpler to improve context management as we go cause we
have a nice object to work with

Starts refactoring allowing for a single message to have
multiple uploads throughout

* transplant method to message builder

* chipping away at inline uploads

* image support is improved but not fully fixed yet

partially working in anthropic, still got quite a few dialects to go

* open ai and claude are now working

* Gemini is now working as well

* fix nova

* more dialects...

* fix ollama

* fix specs

* update artifact fixed

* more tests

* spam scanner

* pass more specs

* bunch of specs improved

* more bug fixes.

* all the rest of the tests are working

* improve tests coverage and ensure custom tools are aware of new context object

* tests are working, but we need more tests

* resolve merge conflict

* new preamble and expanded specs on ai tool

* remove concept of "standalone tools"

This is no longer needed, we can set custom raw, tool details are injected into tool calls
2025-03-31 12:39:07 -03:00
Natalie Tay f7536181af
DEV: Update solved report due to changes in solved plugin (#1212) 2025-03-25 15:15:30 +08:00
Sam 1dde82eb58
FEATURE: allow specifying tool use none in completion prompt
This PR adds support for disabling further tool calls by setting tool_choice to :none across all supported LLM providers:

- OpenAI: Uses "none" tool_choice parameter
- Anthropic: Uses {type: "none"} and adds a prefill message to prevent confusion
- Gemini: Sets function_calling_config mode to "NONE"
- AWS Bedrock: Doesn't natively support tool disabling, so adds a prefill message

We previously used to disable tool calls by simply removing tool definitions, but this would cause errors with some providers. This implementation uses the supported method appropriate for each provider while providing a fallback for Bedrock.

Co-authored-by: Natalie Tay <natalie.tay@gmail.com>

* remove stray puts

* cleaner chain breaker for last tool call (works in thinking)

remove unused code

* improve test

---------

Co-authored-by: Natalie Tay <natalie.tay@gmail.com>
2025-03-25 08:06:43 +11:00
Régis Hanol 2dd7068b46
DEV: add `guardian` argument to `TopicsFilter` callback (#1206)
To match the updates in discourse/discourse#31908
2025-03-24 10:33:18 +01:00
Sam 9211b211f5
FEATURE: silent triage using ai persona (#1193)
This allows for a new mode in persona triage where nothing is posted on topics.

This allows people to perform all triage actions using tools

Additionally introduces new APIs to create chat messages from tools which can be useful in certain moderation scenarios

Co-authored-by: Natalie Tay <natalie.tay@gmail.com>

* remove TODO code

---------

Co-authored-by: Natalie Tay <natalie.tay@gmail.com>
2025-03-17 15:14:09 +11:00
Keegan George 6aaf8a0619
DEV: Use existing topic embeddings when suggesting tags/categories on edit (#1189)
When editing a topic (instead of creating one) and using the
tag/category suggestion buttons. We want to use existing topic
embeddings instead of creating new ones.
2025-03-12 18:52:07 -07:00
Sam 65503a5038
FIX: various issues with llm and triage management (#1186)
- Fix search API to only include column_names when present to make the API less confusing
- Ensure correct LLM is used in PMs by tracking and preferring the last bot user
- Fix persona_id conversion from string to integer in custom fields
- Add missing test for PM triage with no replies - ensure we don't try to auto title topic 
- Ensure bot users are properly added to PMs
- Make title setting optional when replying to posts
- Add ability to control stream_reply behavior

These changes improve reliability and fix edge cases in bot interactions,
particularly in private messages with multiple LLMs and while triaging posts using personas
2025-03-12 18:32:02 +11:00
Sam 8f4cd2fcbd
FEATURE: allow disabling of top_p and temp for thinking models (#1184)
thinking models such as Claude 3.7 Thinking and o1 / o3 do not
support top_p or temp.

Previously you would have to carefully remove it from everywhere
by having it be a provider param we now support blanker removing
without forcing people to update automation rules or personas
2025-03-11 16:54:02 +11:00
Guhyoun Nam f4708d4178
DEV: Ai summary utilizing name instead of username (#1180)
* DEV: Ai summary utilizing name instead of username

* utilize username if name not available

* test added

* test added 2
2025-03-11 14:29:13 +11:00
Sam 168d9d8eb9
FIX: AI triage support and refactor search functionality (#1175)
* FIX: do not add bot user to PM when using responders

* Allow AI tool to call search directly

* remove stray p
2025-03-11 14:26:07 +11:00
Keegan George bb32d0d737
FEATURE: Add ability to disable search discoveries (#1177)
This update adds the ability to disable search discoveries. This can be done through a tooltip when search discoveries are shown. It can also be done in the AI user preferences, which has also been updated to accommodate more than just the one image caption setting.
2025-03-10 14:17:58 -07:00
Roman Rizzi 1ce25c5a8b
DEV: Don't classify post sentiments on creation. (#1174)
We'll rely on the backfill instead, which runs every five minutes. Bump default batch size x10 to avoid lagging.
2025-03-07 14:45:10 -03:00
Sam 01893bb6ed
FEATURE: Add persona-based replies and whisper support to LLM triage (#1170)
This PR enhances the LLM triage automation with several important improvements:

- Add ability to use AI personas for automated replies instead of canned replies
- Add support for whisper responses
- Refactor LLM persona reply functionality into a reusable method
- Add new settings to configure response behavior in automations
- Improve error handling and logging
- Fix handling of personal messages in the triage flow
- Add comprehensive test coverage for new features
- Make personas configurable with more flexible requirements

This allows for more dynamic and context-aware responses in automated workflows, with better control over visibility and attribution.
2025-03-06 17:18:15 +11:00
Sam e255c7a8f0
FEATURE: automation triage using personas (#1126)
## LLM Persona Triage
- Allows automated responses to posts using AI personas
- Configurable to respond as regular posts or whispers
- Adds context-aware formatting for topics and private messages
- Provides special handling for topic metadata (title, category, tags)

## LLM Tool Triage
- Enables custom AI tools to process and respond to posts
- Tools can analyze post content and invoke personas when needed
- Zero-parameter tools can be used for automated workflows
- Not enabled in production yet

## Implementation Details
- Added new scriptable registration in discourse_automation/ directory
- Created core implementation in lib/automation/ modules
- Enhanced PromptMessagesBuilder with topic-style formatting
- Added helper methods for persona and tool selection in UI
- Extended AI Bot functionality to support whisper responses
- Added rate limiting to prevent abuse

## Other Changes
- Added comprehensive test coverage for both automation types
- Enhanced tool runner with LLM integration capabilities
- Improved error handling and logging

This feature allows forum admins to configure AI personas to automatically respond to posts based on custom criteria and leverage AI tools for more complex triage workflows.

Tool Triage has been disabled in production while we finalize details of new scripting capabilities.
2025-03-06 09:41:09 +11:00
Sam f6eedf3e0b
FEATURE: implement thinking token support (#1155)
adds support for "thinking tokens" - a feature that exposes the model's reasoning process before providing the final response. Key improvements include:

- Add a new Thinking class to handle thinking content from LLMs
- Modify endpoints (Claude, AWS Bedrock) to handle thinking output
- Update AI bot to display thinking in collapsible details section
- Fix SEARCH/REPLACE blocks to support empty replacement strings and general improvements to artifact editing
- Allow configurable temperature in triage and report automations
- Various bug fixes and improvements to diff parsing
2025-03-04 12:22:30 +11:00
Sam fe19133dd4
FEATURE: full support for Sonnet 3.7 (#1151)
* FEATURE: full support for Sonnet 3.7

- Adds support for Sonnet 3.7 with reasoning on bedrock and anthropic
- Fixes regression where provider params were not populated

Note. reasoning tokens are hardcoded to minimum of 100 maximum of 65536

* FIX: open ai non reasoning models need to use deprecate max_tokens
2025-02-25 17:32:12 +11:00
Sam 12f00a62d2
FIX: use max_completion_tokens for open ai models (#1134)
max_tokens is now deprecated per API
2025-02-19 15:49:15 +11:00
Sam 0c9466059c
DEV: improve artifact editing and eval system (#1130)
- Add non-contiguous search/replace support using ... syntax
- Add judge support for evaluating LLM outputs with ratings
- Improve error handling and reporting in eval runner
- Add full section replacement support without search blocks
- Add fabricators and specs for artifact diffing
- Track failed searches to improve debugging
- Add JS syntax validation for artifact versions in eval system
- Update prompt documentation with clear guidelines

* improve eval output

* move error handling

* llm as a judge

* fix spec

* small note on evals
2025-02-19 15:44:33 +11:00
Martin Brennan 0582e75205
DEV: Skip PDF tests (#1129)
CI=1 is not set on our internal build system,
we need to fix that but for now let's unblock the build
2025-02-18 10:17:11 +10:00
Sam ce79a18790
FEATURE: Native PDF support (#1127)
* FEATURE: Native PDF support

This amends it so we use PDF Reader gem to extract text from PDFs

* This means that our simple pdf eval passes at last

* fix spec

* skip test in CI

* test file support

* Update lib/utils/image_to_text.rb

Co-authored-by: Alan Guo Xiang Tan <gxtan1990@gmail.com>

* address pr comments

---------

Co-authored-by: Alan Guo Xiang Tan <gxtan1990@gmail.com>
2025-02-18 09:22:57 +11:00
Sam 5e80f93e4c
FEATURE: PDF support for rag pipeline (#1118)
This PR introduces several enhancements and refactorings to the AI Persona and RAG (Retrieval-Augmented Generation) functionalities within the discourse-ai plugin. Here's a breakdown of the changes:

**1. LLM Model Association for RAG and Personas:**

-   **New Database Columns:** Adds `rag_llm_model_id` to both `ai_personas` and `ai_tools` tables. This allows specifying a dedicated LLM for RAG indexing, separate from the persona's primary LLM.  Adds `default_llm_id` and `question_consolidator_llm_id` to `ai_personas`.
-   **Migration:**  Includes a migration (`20250210032345_migrate_persona_to_llm_model_id.rb`) to populate the new `default_llm_id` and `question_consolidator_llm_id` columns in `ai_personas` based on the existing `default_llm` and `question_consolidator_llm` string columns, and a post migration to remove the latter.
-   **Model Changes:**  The `AiPersona` and `AiTool` models now `belong_to` an `LlmModel` via `rag_llm_model_id`. The `LlmModel.proxy` method now accepts an `LlmModel` instance instead of just an identifier.  `AiPersona` now has `default_llm_id` and `question_consolidator_llm_id` attributes.
-   **UI Updates:**  The AI Persona and AI Tool editors in the admin panel now allow selecting an LLM for RAG indexing (if PDF/image support is enabled).  The RAG options component displays an LLM selector.
-   **Serialization:** The serializers (`AiCustomToolSerializer`, `AiCustomToolListSerializer`, `LocalizedAiPersonaSerializer`) have been updated to include the new `rag_llm_model_id`, `default_llm_id` and `question_consolidator_llm_id` attributes.

**2. PDF and Image Support for RAG:**

-   **Site Setting:** Introduces a new hidden site setting, `ai_rag_pdf_images_enabled`, to control whether PDF and image files can be indexed for RAG. This defaults to `false`.
-   **File Upload Validation:** The `RagDocumentFragmentsController` now checks the `ai_rag_pdf_images_enabled` setting and allows PDF, PNG, JPG, and JPEG files if enabled.  Error handling is included for cases where PDF/image indexing is attempted with the setting disabled.
-   **PDF Processing:** Adds a new utility class, `DiscourseAi::Utils::PdfToImages`, which uses ImageMagick (`magick`) to convert PDF pages into individual PNG images. A maximum PDF size and conversion timeout are enforced.
-   **Image Processing:** A new utility class, `DiscourseAi::Utils::ImageToText`, is included to handle OCR for the images and PDFs.
-   **RAG Digestion Job:** The `DigestRagUpload` job now handles PDF and image uploads. It uses `PdfToImages` and `ImageToText` to extract text and create document fragments.
-   **UI Updates:**  The RAG uploader component now accepts PDF and image file types if `ai_rag_pdf_images_enabled` is true. The UI text is adjusted to indicate supported file types.

**3. Refactoring and Improvements:**

-   **LLM Enumeration:** The `DiscourseAi::Configuration::LlmEnumerator` now provides a `values_for_serialization` method, which returns a simplified array of LLM data (id, name, vision_enabled) suitable for use in serializers. This avoids exposing unnecessary details to the frontend.
-   **AI Helper:** The `AiHelper::Assistant` now takes optional `helper_llm` and `image_caption_llm` parameters in its constructor, allowing for greater flexibility.
-   **Bot and Persona Updates:** Several updates were made across the codebase, changing the string based association to a LLM to the new model based.
-   **Audit Logs:** The `DiscourseAi::Completions::Endpoints::Base` now formats raw request payloads as pretty JSON for easier auditing.
- **Eval Script:** An evaluation script is included.

**4. Testing:**

-    The PR introduces a new eval system for LLMs, this allows us to test how functionality works across various LLM providers. This lives in `/evals`
2025-02-14 12:15:07 +11:00
Martin Brennan 7b1bdbde6d
FIX: Check post action creator result when flagging spam (#1119)
Currently in core re-flagging something that is already flagged as spam
is not supported, long term we may want to support this but in the meantime
we should not be silencing/hiding if the PostActionCreator fails
when flagging things as spam.

---------

Co-authored-by: Ted Johansson <drenmi@gmail.com>
2025-02-11 13:29:27 +10:00
Hoa Nguyen b60926c6e6
FEATURE: Tool name validation (#842)
* FEATURE: Tool name validation

- Add unique index to the name column of the ai_tools table
- correct our tests for AiToolController
- tool_name field which will be used to represent to LLM
- Add tool_name to Tools's presets
- Add duplicate tools validation for AiPersona
- Add unique constraint to the name column of the ai_tools table

* DEV: Validate duplicate tool_name between builin tools and custom tools

* lint

* chore: fix linting

* fix conlict mistakes

* chore: correct icon class

* chore: fix failed specs

* Add max_length to tool_name

* chore: correct the option name

* lintings

* fix lintings
2025-02-07 14:34:47 +11:00
Roman Rizzi e52045ebdc
DEV: Robust check for embeddings enabled (#1116) 2025-02-06 12:18:55 -03:00
Roman Rizzi 1b1b44353b
FEATURE: Changes to summaries' outdated logic. (#1108)
Before this change, a summary was only outdated when new content appeared, for topics with "best replies", when the query returned different results. The intent behind this change is to detect when a summary is outdated as a result of an edit.

Additionally, we are changing the backfill candidates query to compare "ai_summary_backfill_topic_max_age_days" against "last_posted_at" instead of "created_at", to catch long-lived, active topics. This was discussed here: https://meta.discourse.org/t/ai-summarization-backfill-is-stuck-keeps-regenerating-the-same-topic/347088/14?u=roman_rizzi
2025-02-04 09:31:11 -03:00
Sam 43c56d7c92
FIX: need to be able to search replace within lines (#1110)
(this is needed for very simple diffs and HTML)
2025-02-04 18:16:52 +11:00