mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-17 23:35:54 +01:00
Merge pull request #296139 from microsoft/benibenj/lazy-tarsier
Agent sessions feedback for sessions window
This commit is contained in:
@@ -245,7 +245,6 @@ export class MenuId {
|
||||
static readonly MergeInputResultToolbar = new MenuId('MergeToolbarResultToolbar');
|
||||
static readonly InlineSuggestionToolbar = new MenuId('InlineSuggestionToolbar');
|
||||
static readonly InlineEditToolbar = new MenuId('InlineEditToolbar');
|
||||
static readonly AgentFeedbackEditorContent = new MenuId('AgentFeedbackEditorContent');
|
||||
static readonly ChatContext = new MenuId('ChatContext');
|
||||
static readonly ChatCodeBlock = new MenuId('ChatCodeblock');
|
||||
static readonly ChatCompareBlock = new MenuId('ChatCompareBlock');
|
||||
|
||||
@@ -24,4 +24,5 @@ export const Menus = {
|
||||
AuxiliaryBarTitleLeft: new MenuId('SessionsAuxiliaryBarTitleLeft'),
|
||||
SidebarFooter: new MenuId('SessionsSidebarFooter'),
|
||||
SidebarCustomizations: new MenuId('SessionsSidebarCustomizations'),
|
||||
AgentFeedbackEditorContent: new MenuId('AgentFeedbackEditorContent'),
|
||||
} as const;
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import './agentFeedbackEditorInputContribution.js';
|
||||
import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';
|
||||
import { registerWorkbenchContribution2, WorkbenchPhase } from '../../../../workbench/common/contributions.js';
|
||||
import { AgentFeedbackService, IAgentFeedbackService } from './agentFeedbackService.js';
|
||||
import { AgentFeedbackAttachmentContribution } from './agentFeedbackAttachment.js';
|
||||
import { AgentFeedbackEditorOverlay } from './agentFeedbackEditorOverlay.js';
|
||||
import { registerAgentFeedbackEditorActions } from './agentFeedbackEditorActions.js';
|
||||
|
||||
registerWorkbenchContribution2(AgentFeedbackEditorOverlay.ID, AgentFeedbackEditorOverlay, WorkbenchPhase.AfterRestored);
|
||||
registerWorkbenchContribution2(AgentFeedbackAttachmentContribution.ID, AgentFeedbackAttachmentContribution, WorkbenchPhase.AfterRestored);
|
||||
|
||||
registerAgentFeedbackEditorActions();
|
||||
|
||||
registerSingleton(IAgentFeedbackService, AgentFeedbackService, InstantiationType.Delayed);
|
||||
@@ -3,16 +3,16 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Disposable, DisposableMap } from '../../../../../base/common/lifecycle.js';
|
||||
import { Codicon } from '../../../../../base/common/codicons.js';
|
||||
import { basename } from '../../../../../base/common/resources.js';
|
||||
import { URI } from '../../../../../base/common/uri.js';
|
||||
import { IRange } from '../../../../../editor/common/core/range.js';
|
||||
import { ITextModelService } from '../../../../../editor/common/services/resolverService.js';
|
||||
import { localize } from '../../../../../nls.js';
|
||||
import { Disposable, DisposableMap } from '../../../../base/common/lifecycle.js';
|
||||
import { Codicon } from '../../../../base/common/codicons.js';
|
||||
import { basename } from '../../../../base/common/resources.js';
|
||||
import { URI } from '../../../../base/common/uri.js';
|
||||
import { IRange } from '../../../../editor/common/core/range.js';
|
||||
import { ITextModelService } from '../../../../editor/common/services/resolverService.js';
|
||||
import { localize } from '../../../../nls.js';
|
||||
import { IAgentFeedbackService, IAgentFeedback } from './agentFeedbackService.js';
|
||||
import { IChatWidgetService } from '../chat.js';
|
||||
import { IAgentFeedbackVariableEntry } from '../../common/attachments/chatVariableEntries.js';
|
||||
import { IChatWidgetService } from '../../../../workbench/contrib/chat/browser/chat.js';
|
||||
import { IAgentFeedbackVariableEntry } from '../../../../workbench/contrib/chat/common/attachments/chatVariableEntries.js';
|
||||
|
||||
const ATTACHMENT_ID_PREFIX = 'agentFeedback:';
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import './media/agentFeedbackAttachment.css';
|
||||
import * as dom from '../../../../../base/browser/dom.js';
|
||||
import { Codicon } from '../../../../../base/common/codicons.js';
|
||||
import { ThemeIcon } from '../../../../../base/common/themables.js';
|
||||
import { Disposable } from '../../../../../base/common/lifecycle.js';
|
||||
import * as event from '../../../../../base/common/event.js';
|
||||
import { localize } from '../../../../../nls.js';
|
||||
import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js';
|
||||
import { IAgentFeedbackVariableEntry } from '../../common/attachments/chatVariableEntries.js';
|
||||
import * as dom from '../../../../base/browser/dom.js';
|
||||
import { Codicon } from '../../../../base/common/codicons.js';
|
||||
import { ThemeIcon } from '../../../../base/common/themables.js';
|
||||
import { Disposable } from '../../../../base/common/lifecycle.js';
|
||||
import * as event from '../../../../base/common/event.js';
|
||||
import { localize } from '../../../../nls.js';
|
||||
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
|
||||
import { IAgentFeedbackVariableEntry } from '../../../../workbench/contrib/chat/common/attachments/chatVariableEntries.js';
|
||||
import { AgentFeedbackHover } from './agentFeedbackHover.js';
|
||||
|
||||
/**
|
||||
@@ -3,20 +3,21 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Codicon } from '../../../../../base/common/codicons.js';
|
||||
import { localize, localize2 } from '../../../../../nls.js';
|
||||
import { Action2, MenuId, MenuRegistry, registerAction2 } from '../../../../../platform/actions/common/actions.js';
|
||||
import { ContextKeyExpr } from '../../../../../platform/contextkey/common/contextkey.js';
|
||||
import { ServicesAccessor } from '../../../../../platform/instantiation/common/instantiation.js';
|
||||
import { URI } from '../../../../../base/common/uri.js';
|
||||
import { isEqual } from '../../../../../base/common/resources.js';
|
||||
import { EditorsOrder, IEditorIdentifier } from '../../../../common/editor.js';
|
||||
import { IEditorService } from '../../../../services/editor/common/editorService.js';
|
||||
import { IChatWidgetService } from '../chat.js';
|
||||
import { ChatContextKeys } from '../../common/actions/chatContextKeys.js';
|
||||
import { CHAT_CATEGORY } from '../actions/chatActions.js';
|
||||
import { Codicon } from '../../../../base/common/codicons.js';
|
||||
import { localize, localize2 } from '../../../../nls.js';
|
||||
import { Action2, MenuRegistry, registerAction2 } from '../../../../platform/actions/common/actions.js';
|
||||
import { ContextKeyExpr } from '../../../../platform/contextkey/common/contextkey.js';
|
||||
import { ServicesAccessor } from '../../../../platform/instantiation/common/instantiation.js';
|
||||
import { URI } from '../../../../base/common/uri.js';
|
||||
import { isEqual } from '../../../../base/common/resources.js';
|
||||
import { EditorsOrder, IEditorIdentifier } from '../../../../workbench/common/editor.js';
|
||||
import { IEditorService } from '../../../../workbench/services/editor/common/editorService.js';
|
||||
import { IChatWidgetService } from '../../../../workbench/contrib/chat/browser/chat.js';
|
||||
import { ChatContextKeys } from '../../../../workbench/contrib/chat/common/actions/chatContextKeys.js';
|
||||
import { CHAT_CATEGORY } from '../../../../workbench/contrib/chat/browser/actions/chatActions.js';
|
||||
import { IAgentFeedbackService } from './agentFeedbackService.js';
|
||||
import { getActiveResourceCandidates } from './agentFeedbackEditorUtils.js';
|
||||
import { Menus } from '../../../browser/menus.js';
|
||||
|
||||
export const submitFeedbackActionId = 'agentFeedbackEditor.action.submit';
|
||||
export const navigatePreviousFeedbackActionId = 'agentFeedbackEditor.action.navigatePrevious';
|
||||
@@ -61,7 +62,7 @@ class SubmitFeedbackAction extends AgentFeedbackEditorAction {
|
||||
icon: Codicon.send,
|
||||
precondition: ChatContextKeys.enabled,
|
||||
menu: {
|
||||
id: MenuId.AgentFeedbackEditorContent,
|
||||
id: Menus.AgentFeedbackEditorContent,
|
||||
group: 'a_submit',
|
||||
order: 0,
|
||||
when: ChatContextKeys.enabled,
|
||||
@@ -110,7 +111,7 @@ class NavigateFeedbackAction extends AgentFeedbackEditorAction {
|
||||
f1: true,
|
||||
precondition: ChatContextKeys.enabled,
|
||||
menu: {
|
||||
id: MenuId.AgentFeedbackEditorContent,
|
||||
id: Menus.AgentFeedbackEditorContent,
|
||||
group: 'navigate',
|
||||
order: _next ? 2 : 1,
|
||||
when: ChatContextKeys.enabled,
|
||||
@@ -149,7 +150,7 @@ class ClearAllFeedbackAction extends AgentFeedbackEditorAction {
|
||||
f1: true,
|
||||
precondition: ContextKeyExpr.and(ChatContextKeys.enabled),
|
||||
menu: {
|
||||
id: MenuId.AgentFeedbackEditorContent,
|
||||
id: Menus.AgentFeedbackEditorContent,
|
||||
group: 'a_submit',
|
||||
order: 1,
|
||||
when: ChatContextKeys.enabled,
|
||||
@@ -169,7 +170,7 @@ export function registerAgentFeedbackEditorActions(): void {
|
||||
registerAction2(class extends NavigateFeedbackAction { constructor() { super(true); } });
|
||||
registerAction2(ClearAllFeedbackAction);
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.AgentFeedbackEditorContent, {
|
||||
MenuRegistry.appendMenuItem(Menus.AgentFeedbackEditorContent, {
|
||||
command: {
|
||||
id: navigationBearingFakeActionId,
|
||||
title: localize('label', 'Navigation Status'),
|
||||
@@ -0,0 +1,308 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import './media/agentFeedbackEditorInput.css';
|
||||
import { Disposable, DisposableStore } from '../../../../base/common/lifecycle.js';
|
||||
import { ICodeEditor, IOverlayWidget, IOverlayWidgetPosition } from '../../../../editor/browser/editorBrowser.js';
|
||||
import { IEditorContribution } from '../../../../editor/common/editorCommon.js';
|
||||
import { EditorContributionInstantiation, registerEditorContribution } from '../../../../editor/browser/editorExtensions.js';
|
||||
import { EditorOption } from '../../../../editor/common/config/editorOptions.js';
|
||||
import { SelectionDirection } from '../../../../editor/common/core/selection.js';
|
||||
import { URI } from '../../../../base/common/uri.js';
|
||||
import { addStandardDisposableListener, getWindow } from '../../../../base/browser/dom.js';
|
||||
import { KeyCode } from '../../../../base/common/keyCodes.js';
|
||||
import { IAgentFeedbackService } from './agentFeedbackService.js';
|
||||
import { IChatEditingService } from '../../../../workbench/contrib/chat/common/editing/chatEditingService.js';
|
||||
import { IAgentSessionsService } from '../../../../workbench/contrib/chat/browser/agentSessions/agentSessionsService.js';
|
||||
import { getSessionForResource } from './agentFeedbackEditorUtils.js';
|
||||
import { localize } from '../../../../nls.js';
|
||||
|
||||
class AgentFeedbackInputWidget implements IOverlayWidget {
|
||||
|
||||
private static readonly _ID = 'agentFeedback.inputWidget';
|
||||
|
||||
readonly allowEditorOverflow = false;
|
||||
|
||||
private readonly _domNode: HTMLElement;
|
||||
private readonly _inputElement: HTMLInputElement;
|
||||
private _position: IOverlayWidgetPosition | null = null;
|
||||
|
||||
constructor(
|
||||
private readonly _editor: ICodeEditor,
|
||||
) {
|
||||
this._domNode = document.createElement('div');
|
||||
this._domNode.classList.add('agent-feedback-input-widget');
|
||||
this._domNode.style.display = 'none';
|
||||
|
||||
this._inputElement = document.createElement('input');
|
||||
this._inputElement.type = 'text';
|
||||
this._inputElement.placeholder = localize('agentFeedback.addFeedback', "Add Feedback");
|
||||
this._domNode.appendChild(this._inputElement);
|
||||
|
||||
this._editor.applyFontInfo(this._inputElement);
|
||||
}
|
||||
|
||||
getId(): string {
|
||||
return AgentFeedbackInputWidget._ID;
|
||||
}
|
||||
|
||||
getDomNode(): HTMLElement {
|
||||
return this._domNode;
|
||||
}
|
||||
|
||||
getPosition(): IOverlayWidgetPosition | null {
|
||||
return this._position;
|
||||
}
|
||||
|
||||
get inputElement(): HTMLInputElement {
|
||||
return this._inputElement;
|
||||
}
|
||||
|
||||
setPosition(position: IOverlayWidgetPosition | null): void {
|
||||
this._position = position;
|
||||
this._editor.layoutOverlayWidget(this);
|
||||
}
|
||||
|
||||
show(): void {
|
||||
this._domNode.style.display = '';
|
||||
}
|
||||
|
||||
hide(): void {
|
||||
this._domNode.style.display = 'none';
|
||||
}
|
||||
|
||||
clearInput(): void {
|
||||
this._inputElement.value = '';
|
||||
}
|
||||
}
|
||||
|
||||
export class AgentFeedbackEditorInputContribution extends Disposable implements IEditorContribution {
|
||||
|
||||
static readonly ID = 'agentFeedback.editorInputContribution';
|
||||
|
||||
private _widget: AgentFeedbackInputWidget | undefined;
|
||||
private _visible = false;
|
||||
private _mouseDown = false;
|
||||
private _sessionResource: URI | undefined;
|
||||
private readonly _widgetListeners = this._store.add(new DisposableStore());
|
||||
|
||||
constructor(
|
||||
private readonly _editor: ICodeEditor,
|
||||
@IAgentFeedbackService private readonly _agentFeedbackService: IAgentFeedbackService,
|
||||
@IChatEditingService private readonly _chatEditingService: IChatEditingService,
|
||||
@IAgentSessionsService private readonly _agentSessionsService: IAgentSessionsService,
|
||||
) {
|
||||
super();
|
||||
|
||||
this._store.add(this._editor.onDidChangeCursorSelection(() => this._onSelectionChanged()));
|
||||
this._store.add(this._editor.onDidChangeModel(() => this._onModelChanged()));
|
||||
this._store.add(this._editor.onDidScrollChange(() => {
|
||||
if (this._visible) {
|
||||
this._updatePosition();
|
||||
}
|
||||
}));
|
||||
this._store.add(this._editor.onMouseDown(() => {
|
||||
this._mouseDown = true;
|
||||
this._hide();
|
||||
}));
|
||||
this._store.add(this._editor.onMouseUp(() => {
|
||||
this._mouseDown = false;
|
||||
this._onSelectionChanged();
|
||||
}));
|
||||
this._store.add(this._editor.onDidBlurEditorWidget(() => this._hide()));
|
||||
this._store.add(this._editor.onDidFocusEditorWidget(() => this._onSelectionChanged()));
|
||||
}
|
||||
|
||||
private _ensureWidget(): AgentFeedbackInputWidget {
|
||||
if (!this._widget) {
|
||||
this._widget = new AgentFeedbackInputWidget(this._editor);
|
||||
this._editor.addOverlayWidget(this._widget);
|
||||
}
|
||||
return this._widget;
|
||||
}
|
||||
|
||||
private _onModelChanged(): void {
|
||||
this._hide();
|
||||
this._sessionResource = undefined;
|
||||
}
|
||||
|
||||
private _onSelectionChanged(): void {
|
||||
if (this._mouseDown || !this._editor.hasWidgetFocus()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const selection = this._editor.getSelection();
|
||||
if (!selection || selection.isEmpty()) {
|
||||
this._hide();
|
||||
return;
|
||||
}
|
||||
|
||||
const model = this._editor.getModel();
|
||||
if (!model) {
|
||||
this._hide();
|
||||
return;
|
||||
}
|
||||
|
||||
const match = getSessionForResource(model.uri, this._chatEditingService, this._agentSessionsService);
|
||||
if (!match) {
|
||||
this._hide();
|
||||
return;
|
||||
}
|
||||
|
||||
this._sessionResource = match.sessionResource;
|
||||
this._show();
|
||||
}
|
||||
|
||||
private _show(): void {
|
||||
const widget = this._ensureWidget();
|
||||
|
||||
if (!this._visible) {
|
||||
this._visible = true;
|
||||
this._registerWidgetListeners(widget);
|
||||
}
|
||||
|
||||
widget.clearInput();
|
||||
widget.show();
|
||||
this._updatePosition();
|
||||
}
|
||||
|
||||
private _hide(): void {
|
||||
if (!this._visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._visible = false;
|
||||
this._widgetListeners.clear();
|
||||
|
||||
if (this._widget) {
|
||||
this._widget.hide();
|
||||
this._widget.setPosition(null);
|
||||
this._widget.clearInput();
|
||||
}
|
||||
}
|
||||
|
||||
private _registerWidgetListeners(widget: AgentFeedbackInputWidget): void {
|
||||
this._widgetListeners.clear();
|
||||
|
||||
// Listen for keydown on the editor dom node to detect when the user starts typing
|
||||
const editorDomNode = this._editor.getDomNode();
|
||||
if (editorDomNode) {
|
||||
this._widgetListeners.add(addStandardDisposableListener(editorDomNode, 'keydown', e => {
|
||||
if (!this._visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't focus if a modifier key is pressed alone
|
||||
if (e.keyCode === KeyCode.Ctrl || e.keyCode === KeyCode.Shift || e.keyCode === KeyCode.Alt || e.keyCode === KeyCode.Meta) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't focus if any modifier is held (keyboard shortcuts)
|
||||
if (e.ctrlKey || e.altKey || e.metaKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't capture Escape at this level - let it fall through to the input handler if focused
|
||||
if (e.keyCode === KeyCode.Escape) {
|
||||
this._hide();
|
||||
this._editor.focus();
|
||||
return;
|
||||
}
|
||||
|
||||
// If the input is not focused, focus it and let the keystroke go through
|
||||
if (getWindow(widget.inputElement).document.activeElement !== widget.inputElement) {
|
||||
widget.inputElement.focus();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
// Listen for keydown on the input element
|
||||
this._widgetListeners.add(addStandardDisposableListener(widget.inputElement, 'keydown', e => {
|
||||
if (e.keyCode === KeyCode.Escape) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this._hide();
|
||||
this._editor.focus();
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.keyCode === KeyCode.Enter) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this._submit(widget);
|
||||
return;
|
||||
}
|
||||
}));
|
||||
|
||||
// Stop propagation of input events so the editor doesn't handle them
|
||||
this._widgetListeners.add(addStandardDisposableListener(widget.inputElement, 'keypress', e => {
|
||||
e.stopPropagation();
|
||||
}));
|
||||
}
|
||||
|
||||
private _submit(widget: AgentFeedbackInputWidget): void {
|
||||
const text = widget.inputElement.value.trim();
|
||||
if (!text) {
|
||||
return;
|
||||
}
|
||||
|
||||
const selection = this._editor.getSelection();
|
||||
const model = this._editor.getModel();
|
||||
if (!selection || !model || !this._sessionResource) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._agentFeedbackService.addFeedback(this._sessionResource, model.uri, selection, text);
|
||||
this._hide();
|
||||
this._editor.focus();
|
||||
}
|
||||
|
||||
private _updatePosition(): void {
|
||||
if (!this._widget || !this._visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
const selection = this._editor.getSelection();
|
||||
if (!selection || selection.isEmpty()) {
|
||||
this._hide();
|
||||
return;
|
||||
}
|
||||
|
||||
const cursorPosition = selection.getDirection() === SelectionDirection.LTR
|
||||
? selection.getEndPosition()
|
||||
: selection.getStartPosition();
|
||||
|
||||
const scrolledPosition = this._editor.getScrolledVisiblePosition(cursorPosition);
|
||||
if (!scrolledPosition) {
|
||||
this._widget.setPosition(null);
|
||||
return;
|
||||
}
|
||||
|
||||
const lineHeight = this._editor.getOption(EditorOption.lineHeight);
|
||||
const left = scrolledPosition.left;
|
||||
|
||||
let top: number;
|
||||
if (selection.getDirection() === SelectionDirection.LTR) {
|
||||
// Cursor at end (bottom) of selection → place widget below the cursor line
|
||||
top = scrolledPosition.top + lineHeight;
|
||||
} else {
|
||||
// Cursor at start (top) of selection → place widget above the cursor line
|
||||
const widgetHeight = this._widget.getDomNode().offsetHeight || 30;
|
||||
top = scrolledPosition.top - widgetHeight;
|
||||
}
|
||||
|
||||
this._widget.setPosition({ preference: { top, left } });
|
||||
}
|
||||
|
||||
override dispose(): void {
|
||||
if (this._widget) {
|
||||
this._editor.removeOverlayWidget(this._widget);
|
||||
this._widget = undefined;
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
registerEditorContribution(AgentFeedbackEditorInputContribution.ID, AgentFeedbackEditorInputContribution, EditorContributionInstantiation.Eventually);
|
||||
@@ -4,25 +4,25 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import './media/agentFeedbackEditorOverlay.css';
|
||||
import { Disposable, DisposableMap, DisposableStore, combinedDisposable, toDisposable } from '../../../../../base/common/lifecycle.js';
|
||||
import { autorun, observableFromEvent, observableSignalFromEvent, observableValue } from '../../../../../base/common/observable.js';
|
||||
import { ActionViewItem, IBaseActionViewItemOptions } from '../../../../../base/browser/ui/actionbar/actionViewItems.js';
|
||||
import { IAction } from '../../../../../base/common/actions.js';
|
||||
import { Event } from '../../../../../base/common/event.js';
|
||||
import { HiddenItemStrategy, MenuWorkbenchToolBar } from '../../../../../platform/actions/browser/toolbar.js';
|
||||
import { MenuId } from '../../../../../platform/actions/common/actions.js';
|
||||
import { IContextKeyService } from '../../../../../platform/contextkey/common/contextkey.js';
|
||||
import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js';
|
||||
import { ServiceCollection } from '../../../../../platform/instantiation/common/serviceCollection.js';
|
||||
import { IKeybindingService } from '../../../../../platform/keybinding/common/keybinding.js';
|
||||
import { IWorkbenchContribution } from '../../../../common/contributions.js';
|
||||
import { EditorGroupView } from '../../../../browser/parts/editor/editorGroupView.js';
|
||||
import { IEditorGroup, IEditorGroupsService } from '../../../../services/editor/common/editorGroupsService.js';
|
||||
import { Disposable, DisposableMap, DisposableStore, combinedDisposable, toDisposable } from '../../../../base/common/lifecycle.js';
|
||||
import { autorun, observableFromEvent, observableSignalFromEvent, observableValue } from '../../../../base/common/observable.js';
|
||||
import { ActionViewItem, IBaseActionViewItemOptions } from '../../../../base/browser/ui/actionbar/actionViewItems.js';
|
||||
import { IAction } from '../../../../base/common/actions.js';
|
||||
import { Event } from '../../../../base/common/event.js';
|
||||
import { HiddenItemStrategy, MenuWorkbenchToolBar } from '../../../../platform/actions/browser/toolbar.js';
|
||||
import { IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js';
|
||||
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
|
||||
import { ServiceCollection } from '../../../../platform/instantiation/common/serviceCollection.js';
|
||||
import { IKeybindingService } from '../../../../platform/keybinding/common/keybinding.js';
|
||||
import { IWorkbenchContribution } from '../../../../workbench/common/contributions.js';
|
||||
import { EditorGroupView } from '../../../../workbench/browser/parts/editor/editorGroupView.js';
|
||||
import { IEditorGroup, IEditorGroupsService } from '../../../../workbench/services/editor/common/editorGroupsService.js';
|
||||
import { IAgentFeedbackService } from './agentFeedbackService.js';
|
||||
import { navigateNextFeedbackActionId, navigatePreviousFeedbackActionId, navigationBearingFakeActionId, submitFeedbackActionId } from './agentFeedbackEditorActions.js';
|
||||
import { assertType } from '../../../../../base/common/types.js';
|
||||
import { localize } from '../../../../../nls.js';
|
||||
import { assertType } from '../../../../base/common/types.js';
|
||||
import { localize } from '../../../../nls.js';
|
||||
import { getActiveResourceCandidates } from './agentFeedbackEditorUtils.js';
|
||||
import { Menus } from '../../../browser/menus.js';
|
||||
|
||||
class AgentFeedbackActionViewItem extends ActionViewItem {
|
||||
|
||||
@@ -84,7 +84,7 @@ class AgentFeedbackOverlayWidget extends Disposable {
|
||||
this._domNode.appendChild(this._toolbarNode);
|
||||
}
|
||||
|
||||
this._showStore.add(this._instaService.createInstance(MenuWorkbenchToolBar, this._toolbarNode, MenuId.AgentFeedbackEditorContent, {
|
||||
this._showStore.add(this._instaService.createInstance(MenuWorkbenchToolBar, this._toolbarNode, Menus.AgentFeedbackEditorContent, {
|
||||
telemetrySource: 'agentFeedback.overlayToolbar',
|
||||
hiddenItemStrategy: HiddenItemStrategy.Ignore,
|
||||
toolbarOptions: {
|
||||
@@ -0,0 +1,60 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { URI } from '../../../../base/common/uri.js';
|
||||
import { EditorResourceAccessor, SideBySideEditor } from '../../../../workbench/common/editor.js';
|
||||
import { IChatEditingService } from '../../../../workbench/contrib/chat/common/editing/chatEditingService.js';
|
||||
import { IAgentSessionsService } from '../../../../workbench/contrib/chat/browser/agentSessions/agentSessionsService.js';
|
||||
import { agentSessionContainsResource, editingEntriesContainResource } from '../../../../workbench/contrib/chat/browser/sessionResourceMatching.js';
|
||||
|
||||
export interface ISessionResourceMatch {
|
||||
readonly sessionResource: URI;
|
||||
readonly resourceUri: URI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the session that contains the given resource by checking editing sessions and agent sessions.
|
||||
*/
|
||||
export function getSessionForResource(
|
||||
resourceUri: URI,
|
||||
chatEditingService: IChatEditingService,
|
||||
agentSessionsService: IAgentSessionsService,
|
||||
): ISessionResourceMatch | undefined {
|
||||
for (const editingSession of chatEditingService.editingSessionsObs.get()) {
|
||||
if (editingEntriesContainResource(editingSession.entries.get(), resourceUri)) {
|
||||
return { sessionResource: editingSession.chatSessionResource, resourceUri };
|
||||
}
|
||||
}
|
||||
|
||||
for (const session of agentSessionsService.model.sessions) {
|
||||
if (agentSessionContainsResource(session, resourceUri)) {
|
||||
return { sessionResource: session.resource, resourceUri };
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function getActiveResourceCandidates(input: Parameters<typeof EditorResourceAccessor.getOriginalUri>[0]): URI[] {
|
||||
const result: URI[] = [];
|
||||
const resources = EditorResourceAccessor.getOriginalUri(input, { supportSideBySide: SideBySideEditor.BOTH });
|
||||
if (!resources) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (URI.isUri(resources)) {
|
||||
result.push(resources);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (resources.secondary) {
|
||||
result.push(resources.secondary);
|
||||
}
|
||||
if (resources.primary) {
|
||||
result.push(resources.primary);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -3,21 +3,21 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as dom from '../../../../../base/browser/dom.js';
|
||||
import { HoverStyle } from '../../../../../base/browser/ui/hover/hover.js';
|
||||
import { HoverPosition } from '../../../../../base/browser/ui/hover/hoverWidget.js';
|
||||
import { Codicon } from '../../../../../base/common/codicons.js';
|
||||
import { Disposable, DisposableStore } from '../../../../../base/common/lifecycle.js';
|
||||
import { ThemeIcon } from '../../../../../base/common/themables.js';
|
||||
import { IRange } from '../../../../../editor/common/core/range.js';
|
||||
import { URI } from '../../../../../base/common/uri.js';
|
||||
import { localize } from '../../../../../nls.js';
|
||||
import { IHoverService } from '../../../../../platform/hover/browser/hover.js';
|
||||
import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js';
|
||||
import { IEditorService } from '../../../../services/editor/common/editorService.js';
|
||||
import { DEFAULT_LABELS_CONTAINER, ResourceLabels } from '../../../../browser/labels.js';
|
||||
import * as dom from '../../../../base/browser/dom.js';
|
||||
import { HoverStyle } from '../../../../base/browser/ui/hover/hover.js';
|
||||
import { HoverPosition } from '../../../../base/browser/ui/hover/hoverWidget.js';
|
||||
import { Codicon } from '../../../../base/common/codicons.js';
|
||||
import { Disposable, DisposableStore } from '../../../../base/common/lifecycle.js';
|
||||
import { ThemeIcon } from '../../../../base/common/themables.js';
|
||||
import { IRange } from '../../../../editor/common/core/range.js';
|
||||
import { URI } from '../../../../base/common/uri.js';
|
||||
import { localize } from '../../../../nls.js';
|
||||
import { IHoverService } from '../../../../platform/hover/browser/hover.js';
|
||||
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
|
||||
import { IEditorService } from '../../../../workbench/services/editor/common/editorService.js';
|
||||
import { DEFAULT_LABELS_CONTAINER, ResourceLabels } from '../../../../workbench/browser/labels.js';
|
||||
import { IAgentFeedbackService } from './agentFeedbackService.js';
|
||||
import { IAgentFeedbackVariableEntry } from '../../common/attachments/chatVariableEntries.js';
|
||||
import { IAgentFeedbackVariableEntry } from '../../../../workbench/contrib/chat/common/attachments/chatVariableEntries.js';
|
||||
|
||||
/**
|
||||
* Creates the custom hover content for the "N comments" attachment.
|
||||
@@ -3,24 +3,24 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Emitter, Event } from '../../../../../base/common/event.js';
|
||||
import { Disposable } from '../../../../../base/common/lifecycle.js';
|
||||
import { URI } from '../../../../../base/common/uri.js';
|
||||
import { IRange } from '../../../../../editor/common/core/range.js';
|
||||
import { Comment, CommentThread, CommentThreadCollapsibleState, CommentThreadState, CommentInput } from '../../../../../editor/common/languages.js';
|
||||
import { createDecorator, ServicesAccessor } from '../../../../../platform/instantiation/common/instantiation.js';
|
||||
import { ICommentController, ICommentInfo, ICommentService, INotebookCommentInfo } from '../../../comments/browser/commentService.js';
|
||||
import { CancellationToken } from '../../../../../base/common/cancellation.js';
|
||||
import { generateUuid } from '../../../../../base/common/uuid.js';
|
||||
import { registerAction2, Action2, MenuId } from '../../../../../platform/actions/common/actions.js';
|
||||
import { ContextKeyExpr } from '../../../../../platform/contextkey/common/contextkey.js';
|
||||
import { Codicon } from '../../../../../base/common/codicons.js';
|
||||
import { localize } from '../../../../../nls.js';
|
||||
import { isEqual } from '../../../../../base/common/resources.js';
|
||||
import { IChatEditingService } from '../../common/editing/chatEditingService.js';
|
||||
import { IAgentSessionsService } from '../agentSessions/agentSessionsService.js';
|
||||
import { agentSessionContainsResource, editingEntriesContainResource } from '../sessionResourceMatching.js';
|
||||
import { IChatWidget, IChatWidgetService } from '../chat.js';
|
||||
import { Emitter, Event } from '../../../../base/common/event.js';
|
||||
import { Disposable } from '../../../../base/common/lifecycle.js';
|
||||
import { URI } from '../../../../base/common/uri.js';
|
||||
import { IRange } from '../../../../editor/common/core/range.js';
|
||||
import { Comment, CommentThread, CommentThreadCollapsibleState, CommentThreadState, CommentInput } from '../../../../editor/common/languages.js';
|
||||
import { createDecorator, ServicesAccessor } from '../../../../platform/instantiation/common/instantiation.js';
|
||||
import { ICommentController, ICommentInfo, ICommentService, INotebookCommentInfo } from '../../../../workbench/contrib/comments/browser/commentService.js';
|
||||
import { CancellationToken } from '../../../../base/common/cancellation.js';
|
||||
import { generateUuid } from '../../../../base/common/uuid.js';
|
||||
import { registerAction2, Action2, MenuId } from '../../../../platform/actions/common/actions.js';
|
||||
import { ContextKeyExpr } from '../../../../platform/contextkey/common/contextkey.js';
|
||||
import { Codicon } from '../../../../base/common/codicons.js';
|
||||
import { localize } from '../../../../nls.js';
|
||||
import { isEqual } from '../../../../base/common/resources.js';
|
||||
import { IChatEditingService } from '../../../../workbench/contrib/chat/common/editing/chatEditingService.js';
|
||||
import { IAgentSessionsService } from '../../../../workbench/contrib/chat/browser/agentSessions/agentSessionsService.js';
|
||||
import { agentSessionContainsResource, editingEntriesContainResource } from '../../../../workbench/contrib/chat/browser/sessionResourceMatching.js';
|
||||
import { IChatWidget, IChatWidgetService } from '../../../../workbench/contrib/chat/browser/chat.js';
|
||||
|
||||
// --- Types --------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.agent-feedback-input-widget {
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
background-color: var(--vscode-editorWidget-background);
|
||||
border: 1px solid var(--vscode-editorWidget-border, var(--vscode-contrastBorder));
|
||||
box-shadow: 0 2px 8px var(--vscode-widget-shadow);
|
||||
border-radius: 4px;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.agent-feedback-input-widget input {
|
||||
background-color: var(--vscode-input-background);
|
||||
border: 1px solid var(--vscode-input-border, transparent);
|
||||
color: var(--vscode-input-foreground);
|
||||
border-radius: 2px;
|
||||
padding: 2px 6px;
|
||||
outline: none;
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
.agent-feedback-input-widget input:focus {
|
||||
border-color: var(--vscode-focusBorder);
|
||||
}
|
||||
|
||||
.agent-feedback-input-widget input::placeholder {
|
||||
color: var(--vscode-input-placeholderForeground);
|
||||
}
|
||||
@@ -206,7 +206,7 @@ import '../workbench/contrib/speech/browser/speech.contribution.js';
|
||||
|
||||
// Chat
|
||||
import '../workbench/contrib/chat/browser/chat.contribution.js';
|
||||
import '../workbench/contrib/inlineChat/browser/inlineChat.contribution.js';
|
||||
//import '../workbench/contrib/inlineChat/browser/inlineChat.contribution.js';
|
||||
import '../workbench/contrib/mcp/browser/mcp.contribution.js';
|
||||
import '../workbench/contrib/chat/browser/chatSessions/chatSessions.contribution.js';
|
||||
import '../workbench/contrib/chat/browser/contextContrib/chatContext.contribution.js';
|
||||
|
||||
@@ -165,7 +165,10 @@ import '../workbench/contrib/remoteTunnel/electron-browser/remoteTunnel.contribu
|
||||
|
||||
// Chat
|
||||
import '../workbench/contrib/chat/electron-browser/chat.contribution.js';
|
||||
import '../workbench/contrib/inlineChat/electron-browser/inlineChat.contribution.js';
|
||||
//import '../workbench/contrib/inlineChat/electron-browser/inlineChat.contribution.js';
|
||||
|
||||
import './contrib/agentFeedback/browser/agentFeedback.contribution.js';
|
||||
|
||||
// Encryption
|
||||
import '../workbench/contrib/encryption/electron-browser/encryption.contribution.js';
|
||||
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { URI } from '../../../../../base/common/uri.js';
|
||||
import { EditorResourceAccessor, SideBySideEditor } from '../../../../common/editor.js';
|
||||
|
||||
export function getActiveResourceCandidates(input: Parameters<typeof EditorResourceAccessor.getOriginalUri>[0]): URI[] {
|
||||
const result: URI[] = [];
|
||||
const resources = EditorResourceAccessor.getOriginalUri(input, { supportSideBySide: SideBySideEditor.BOTH });
|
||||
if (!resources) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (URI.isUri(resources)) {
|
||||
result.push(resources);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (resources.secondary) {
|
||||
result.push(resources.secondary);
|
||||
}
|
||||
if (resources.primary) {
|
||||
result.push(resources.primary);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -141,10 +141,6 @@ import { ChatWindowNotifier } from './chatWindowNotifier.js';
|
||||
import { ChatRepoInfoContribution } from './chatRepoInfo.js';
|
||||
import { VALID_PROMPT_FOLDER_PATTERN } from '../common/promptSyntax/utils/promptFilesLocator.js';
|
||||
import { ChatTipService, IChatTipService } from './chatTipService.js';
|
||||
import { AgentFeedbackService, IAgentFeedbackService } from './agentFeedback/agentFeedbackService.js';
|
||||
import { AgentFeedbackAttachmentContribution } from './agentFeedback/agentFeedbackAttachment.js';
|
||||
import { AgentFeedbackEditorOverlay } from './agentFeedback/agentFeedbackEditorOverlay.js';
|
||||
import { registerAgentFeedbackEditorActions } from './agentFeedback/agentFeedbackEditorActions.js';
|
||||
import { ChatQueuePickerRendering } from './widget/input/chatQueuePickerActionItem.js';
|
||||
import { ExploreAgentDefaultModel } from './exploreAgentDefaultModel.js';
|
||||
import { PlanAgentDefaultModel } from './planAgentDefaultModel.js';
|
||||
@@ -1482,7 +1478,6 @@ registerWorkbenchContribution2(ChatAgentRecommendation.ID, ChatAgentRecommendati
|
||||
registerWorkbenchContribution2(ChatEditingEditorAccessibility.ID, ChatEditingEditorAccessibility, WorkbenchPhase.AfterRestored);
|
||||
registerWorkbenchContribution2(ChatQueuePickerRendering.ID, ChatQueuePickerRendering, WorkbenchPhase.BlockRestore);
|
||||
registerWorkbenchContribution2(ChatEditingEditorOverlay.ID, ChatEditingEditorOverlay, WorkbenchPhase.AfterRestored);
|
||||
registerWorkbenchContribution2(AgentFeedbackEditorOverlay.ID, AgentFeedbackEditorOverlay, WorkbenchPhase.AfterRestored);
|
||||
registerWorkbenchContribution2(SimpleBrowserOverlay.ID, SimpleBrowserOverlay, WorkbenchPhase.AfterRestored);
|
||||
registerWorkbenchContribution2(ChatEditingEditorContextKeys.ID, ChatEditingEditorContextKeys, WorkbenchPhase.AfterRestored);
|
||||
registerWorkbenchContribution2(ChatTransferContribution.ID, ChatTransferContribution, WorkbenchPhase.BlockRestore);
|
||||
@@ -1494,7 +1489,6 @@ registerWorkbenchContribution2(UserToolSetsContributions.ID, UserToolSetsContrib
|
||||
registerWorkbenchContribution2(PromptLanguageFeaturesProvider.ID, PromptLanguageFeaturesProvider, WorkbenchPhase.Eventually);
|
||||
registerWorkbenchContribution2(ChatWindowNotifier.ID, ChatWindowNotifier, WorkbenchPhase.AfterRestored);
|
||||
registerWorkbenchContribution2(ChatRepoInfoContribution.ID, ChatRepoInfoContribution, WorkbenchPhase.Eventually);
|
||||
registerWorkbenchContribution2(AgentFeedbackAttachmentContribution.ID, AgentFeedbackAttachmentContribution, WorkbenchPhase.AfterRestored);
|
||||
|
||||
registerChatActions();
|
||||
registerChatAccessibilityActions();
|
||||
@@ -1514,7 +1508,6 @@ registerNewChatActions();
|
||||
registerChatContextActions();
|
||||
registerChatDeveloperActions();
|
||||
registerChatEditorActions();
|
||||
registerAgentFeedbackEditorActions();
|
||||
registerChatElicitationActions();
|
||||
registerChatToolActions();
|
||||
registerLanguageModelActions();
|
||||
@@ -1551,6 +1544,5 @@ registerSingleton(IChatTodoListService, ChatTodoListService, InstantiationType.D
|
||||
registerSingleton(IChatOutputRendererService, ChatOutputRendererService, InstantiationType.Delayed);
|
||||
registerSingleton(IChatLayoutService, ChatLayoutService, InstantiationType.Delayed);
|
||||
registerSingleton(IChatTipService, ChatTipService, InstantiationType.Delayed);
|
||||
registerSingleton(IAgentFeedbackService, AgentFeedbackService, InstantiationType.Delayed);
|
||||
|
||||
ChatWidget.CONTRIBS.push(ChatDynamicVariableModel);
|
||||
|
||||
Reference in New Issue
Block a user