Move thread creation to controller level

What does this MR do and why?

Currently the thread finding and creation are spread/duplicated across 3 locations:

  1. GraphQL Ai::Action mutation (controller level)
  2. GraphQL ChatMessagesResolver (controller level)
  3. ChatStorage (for fetching duo_chat_legay thread only if the controller level did not yield a thread)

The combination of the above can be summarized in this spreadsheet:

Screenshot_2025-06-20_at_6.03.26_PM

The logic at ChatStorage (last legacy thread and create legacy thread) is problematic because it sits deeply in the call at model level where organization is not readily available, but currently we need to include organization in thread related SQL operations.

The aim of this MR is to consolidate the Duo Chat thread fetching/creation in one single class ThreadEnsurer, and call it at controller level where organization is easily available.

This is blocked by the duo_chat_early_thread_creation feature flag.

References

Screenshots or screen recordings

Before After

How to set up and validate locally

Enable duo_chat_early_thread_creation and then:

  • Verify Duo Chat on web works, including adding messages, listing threads, and deleting threads
  • Verify Duo Chat on IDE works

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Related to #501150 (closed)

Edited by Mark Chao

Merge request reports

Loading