Duo Chat UI - Injected Context
## The Problem We Are Solving
This epic encompasses everything logged in the decision here: https://gitlab.com/gitlab-org/gitlab/-/issues/477564
Here is a demo video of what we're aiming to achieve:

## Component Architecture
We aim to integrate these context features directly into the Duo Chat component. We will create several smaller components under `duo_chat_context` to provide the necessary features.
```mermaid
graph TD
A[GlDuoChat] --> B[GlDuoChatConversation]
B --> C[GlDuoChatMessage]
A --> D[GlDuoChatContextItemMenu - NEW]
A --> E[GlDuoChatContextItemSelections - NEW]
C --> E
D --> F[GlDuoChatContextItemPopover - NEW]
E --> F
```
Brief summary (see the work items for the explanation of each of these components):
- there is an existing parent component (GlDuoChat).
- there is an existing GlDuoChatMessage component, which is a sub-component of GlDuoChatConversation. GlDuoChat imports the conversation component
- We will create 3 new components to enable the context functionality.
- GlDuoChatContextItemMenu - GlDuoChat imports this component
- GlDuoChatContextItemSelections - Both GlDuoChat and GlDuoChatMessage will import this component
- GlDuoChatContextItemPopover - This mini component will display information on a context item. Both the selections component and context item menu will import this component
### AI Context Item
We will have one context item object that will be passed around the life cycle of the DuoChat component, consumer Vue App, VSCode Extension, and Language Server:
```ts
export type AiContextItem = {
id: string;
name: string;
isEnabled: boolean;
info: AiContextItemInfo;
type: AiContextItemType;
} & (
| { type: 'issue' | 'merge_request'; subType?: never }
| { type: 'file'; subType: AiContextItemSubType }
);
export type AiContextItemInfo = {
project?: string;
disabledReasons?: string[];
iid?: number;
relFilePath?: string;
};
export type AiContextItemType = 'issue' | 'merge_request' | 'file';
export type AiContextItemSubType = 'open_tab' | 'local_file_search';
```
Each of these UI components will interface directly with the context item object.
See the parent epic for more information on the lifecycle of this message.
### Duo Chat Context Item API
We will have the following events implemented in the corresponding components:
- `context_item_added`: this event will be emitted to the consumer client when the user selects a context item
- `context_item_removed`: this event will be emitted when the user removes a context item
- `context_search_query`: this event will be emitted when the user executes a search query. This event will be automatically triggered with a blank query at mount, and also when the user types in the input boc \_ `context_item_search_result`: this event will need to be handled by the context item menu for displaying the result items of the search query
## Work Items
<table>
<tr>
<th align="right">work item</th>
<th>Why this is needed</th>
<th>Repository And Issues</th>
</tr>
<tr>
<td>item selections component</td>
<td>
This component will display additional context added to the chat as an item to the chat message.
This lets users know what they've added as context when chatting with Duo. Additional information here: https://gitlab.com/gitlab-org/gitlab/-/issues/477564#note_2036016863
</td>
<td>
https://gitlab.com/gitlab-org/gitlab/-/issues/477685
</td>
</tr>
<tr>
<td>context item menu component</td>
<td>
This component allows users to select the context category they wish to work with, and search for the context item they wish to add to chat.
This menu will be triggered by the `/include` slash command in the initial iteration.
</td>
<td>
https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/issues/1492
</td>
</tr>
<tr>
<td>click to expand or go to context item selection</td>
<td>
When the user clicks the item, this will trigger an event to fetch the item's URL so that the user is navigated to the appropriate item.
eg:
* if the item is a file, clicking on the item will take them to that file
* if the item is a snippet, clicking the item will take them to the code snippet and highlight the selection
</td>
<td>
https://gitlab.com/gitlab-org/gitlab/-/issues/477684
</td>
</tr>
</table>
epic