Open petemill opened 1 year ago
Just a quick note, I don't think we should use web_contents directly in Conversation(Driver), we shouldn't use something from content layer here, instead, I think we might want a delegate maybe named PageContextDelegate which AIChatTabHelper would implement.
Things currently owned by conversation_driver, like ai_chatmetrics(not owned instance), credentialmanager, feedbackapi, should be owned by AIChatService instead if it doesn't need to be one instance for each conversation. Needed things can be passed in the service factory. And Conversation(Driver) can have a raw_ptr if needed for those which will be passed when AIChatService create the conversation.
We can also create and own instances of EngineConsumerClaude, EngineConsumerLlama in AIChatService, and take model parameter for functions which submit queries.
We should also remove the inheritance between tab_helper and conversation_driver, creation of tab_helper will need less parameters since most of things are needed by conversation_driver and not the tab_helper.
Things currently owned by conversation_driver, like ai_chatmetrics(not owned instance), credentialmanager, feedbackapi, should be owned by AIChatService instead
Absolutely
We should also remove the inheritance between tab_helper and conversation_driver, creation of tab_helper will need less parameters since most of things are needed by conversation_driver and not the tab_helper.
Yes that was the plan I had too. I thought it was explicitly mentioned above but maybe an edit wasn't submitted a while ago, or maybe it was in a DM conversation with someone when iOS was started and ConversationDriver
was extracted from the original AIChatTabHelper
, but either way the above was actually designed before ConversationDriver
subclassing AIChatTabHelper
was implemented for iOS. So the implication was that Conversation
and the AIChatTabHelper
were separate classes with an optional association. Content association should be via delegate so that standalone conversations will be nicer.
As of now, most AI Chat functionality is handled by a TabHelper, reflecting the single use-case focused around an active Tab, via the sidebar. Those conversations are not persisted and not accessible outside of the Sidebar for the specific Tab.
A refactor will support:
AIChatService (Profile KeyedService)
Manages conversations for the profile. Stores all conversations in database and manages retrieval.
Functions
AssociatedPageContent
) - Retrieves 0..nConversation
s that are attached to the page content (Tab/WebContents for Desktop/Android)true
if there is an open WebContents for the conversation, and the page contents is retrievable (or in-memory).false
if the conversation was related to a WebContents, but the WebContents is now destroyed.Events
Persistence
Owns
AIChatAPI
(i.e. APIRequestHelper)ai_chat::Conversation
instancesAssociatedContentDelegate
(on desktop implemented byAIChatTabHelper
)Supplements a conversation with page content
ai_chat::Conversation
In-memory store for a conversation and its data. Instances are owned by AIChatService. \ Builds prompts for new messages based on conversation history and metadata.
ai_chat::ConversationEntry
struct
ai_chat::engine_consuming
A set of functions which build and use various prompts based on model and data, makes model decisions, and sends requests to either local LLM or remote API. Might use other files for engine/model-specific constants and algorithms
UI Flow
The mojom between WebUI C++ and WebUI JS will change to provide functions for starting new conversations, getting the conversations list metadata, and providing the entries and other state properties of the active conversation. It will also provide events for both when the active conversation state changes and when the list of all conversations’ metadata changes.
Sidebar
The WebUI c++ knows it is open as a sidebar and has a target Tab WebContents. The UI can then be provided with a specific Conversation to be open at via AIChatTabHelper::GetAssociatedConversation, which will return an existing or new Conversation. The UI will also allow a different conversation to be chosen and made active.
Standalone
The page will open with no conversation selected. A list of all conversations will be displayed as well as a prompt to start a new conversation. Any conversation can be chosen and made active, and new conversations can be created.
Incognito
Incognito and regular profiles will be treated as independent. Incognito version will not use any persistence.
Android
The same WebUI will be used on Android
Storage
We will use SQLite to store all conversations from the regular profile. No conversations from incognito profile will be persisted.