Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 4e58986

Browse files
Merge pull request #637 from codestoryai/init-aidechat
Scaffold empty panel to be used for agent interaction
2 parents 7890fc0 + e1391b8 commit 4e58986

14 files changed

+880
-2
lines changed

build/lib/i18n.resources.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@
183183
"project": "vscode-workbench"
184184
},
185185
{
186-
"name": "vs/workbench/contrib/csChat",
186+
"name": "vs/workbench/contrib/aideChat",
187187
"project": "vscode-workbench"
188188
},
189189
{

extensions/codestory/src/server/applyEdits.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export async function applyEdits(request: SidecarApplyEditsRequest): Promise<Sid
2929
// apply the edits to it
3030
const success = await vscode.workspace.applyEdit(workspaceEdit);
3131
// we also want to save the file at this point after applying the edit
32-
const _ = await vscode.workspace.save(fileUri);
32+
await vscode.workspace.save(fileUri);
3333

3434

3535
// we calculate how many lines we get after replacing the text

src/vs/base/common/network.ts

+3
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ export namespace Schemas {
7979
/** Scheme used for the chat input editor. */
8080
export const vscodeChatSesssion = 'vscode-chat-editor';
8181

82+
/** Scheme used for the aide chat input editor. */
83+
export const vscodeAideChatSesssion = 'vscode-aidechat-editor';
84+
8285
/**
8386
* Scheme used internally for webviews that aren't linked to a resource (i.e. not custom editors)
8487
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { Codicon } from 'vs/base/common/codicons';
7+
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
8+
import { localize2 } from 'vs/nls';
9+
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
10+
import { Registry } from 'vs/platform/registry/common/platform';
11+
import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer';
12+
import { IWorkbenchContribution, registerWorkbenchContribution2, WorkbenchPhase } from 'vs/workbench/common/contributions';
13+
import { IViewContainersRegistry, IViewDescriptor, IViewsRegistry, ViewContainer, ViewContainerLocation, Extensions as ViewExtensions } from 'vs/workbench/common/views';
14+
import { AIDE_CHAT_VIEW_ID } from 'vs/workbench/contrib/aideChat/browser/aideChat';
15+
import { AIDE_CHAT_SIDEBAR_PANEL_ID, AideChatViewPane } from 'vs/workbench/contrib/aideChat/browser/aideChatViewPane';
16+
17+
class AideChatExtensionPointHandler implements IWorkbenchContribution {
18+
static readonly ID = 'workbench.contrib.aideChatExtensionPointHandler';
19+
20+
private _viewContainer: ViewContainer;
21+
22+
constructor() {
23+
this._viewContainer = this.registerViewContainer();
24+
this.registerDefaultParticipantView();
25+
}
26+
27+
private registerDefaultParticipantView(): IDisposable {
28+
const name = 'Aide';
29+
const viewDescriptor: IViewDescriptor[] = [{
30+
id: AIDE_CHAT_VIEW_ID,
31+
containerIcon: this._viewContainer.icon,
32+
containerTitle: this._viewContainer.title.value,
33+
singleViewPaneContainerTitle: this._viewContainer.title.value,
34+
name: { value: name, original: name },
35+
canToggleVisibility: false,
36+
canMoveView: true,
37+
ctorDescriptor: new SyncDescriptor(AideChatViewPane),
38+
}];
39+
Registry.as<IViewsRegistry>(ViewExtensions.ViewsRegistry).registerViews(viewDescriptor, this._viewContainer);
40+
41+
return toDisposable(() => {
42+
Registry.as<IViewsRegistry>(ViewExtensions.ViewsRegistry).deregisterViews(viewDescriptor, this._viewContainer);
43+
});
44+
}
45+
46+
private registerViewContainer(): ViewContainer {
47+
// Register View Container
48+
const title = localize2('aideChat.viewContainer.label', "Aide");
49+
const icon = Codicon.wand;
50+
const viewContainerId = AIDE_CHAT_SIDEBAR_PANEL_ID;
51+
const viewContainer: ViewContainer = Registry.as<IViewContainersRegistry>(ViewExtensions.ViewContainersRegistry).registerViewContainer({
52+
id: viewContainerId,
53+
title,
54+
icon,
55+
ctorDescriptor: new SyncDescriptor(ViewPaneContainer, [viewContainerId, { mergeViewWithContainerWhenSingleView: true }]),
56+
storageId: viewContainerId,
57+
hideIfEmpty: true,
58+
order: 100,
59+
}, ViewContainerLocation.AuxiliaryBar);
60+
61+
return viewContainer;
62+
}
63+
}
64+
65+
registerWorkbenchContribution2(AideChatExtensionPointHandler.ID, AideChatExtensionPointHandler, WorkbenchPhase.BlockStartup);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
export interface IAideChatWidget {
7+
}
8+
9+
export const AIDE_CHAT_VIEW_ID = `workbench.panel.aideChat.view`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { Dimension, IDomPosition } from 'vs/base/browser/dom';
7+
import { CancellationToken } from 'vs/base/common/cancellation';
8+
import { IContextKeyService, IScopedContextKeyService } from 'vs/platform/contextkey/common/contextkey';
9+
import { IEditorOptions } from 'vs/platform/editor/common/editor';
10+
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
11+
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
12+
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
13+
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
14+
import { editorBackground, editorForeground, inputBackground } from 'vs/platform/theme/common/colorRegistry';
15+
import { IThemeService } from 'vs/platform/theme/common/themeService';
16+
import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
17+
import { IEditorOpenContext } from 'vs/workbench/common/editor';
18+
import { Memento } from 'vs/workbench/common/memento';
19+
import { AideChatEditorInput } from 'vs/workbench/contrib/aideChat/browser/aideChatEditorInput';
20+
import { AideChatWidget, IAideChatViewState } from 'vs/workbench/contrib/aideChat/browser/aideChatWidget';
21+
import { IAideChatModel } from 'vs/workbench/contrib/aideChat/common/aideChatModel';
22+
import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService';
23+
24+
export interface IAideChatEditorOptions extends IEditorOptions {
25+
target?: { sessionId: string };
26+
}
27+
28+
export class AideChatEditor extends EditorPane {
29+
private widget!: AideChatWidget;
30+
31+
private _scopedContextKeyService!: IScopedContextKeyService;
32+
override get scopedContextKeyService() {
33+
return this._scopedContextKeyService;
34+
}
35+
36+
private _memento: Memento | undefined;
37+
private _viewState: IAideChatViewState | undefined;
38+
39+
constructor(
40+
group: IEditorGroup,
41+
@ITelemetryService telemetryService: ITelemetryService,
42+
@IThemeService themeService: IThemeService,
43+
@IInstantiationService private readonly instantiationService: IInstantiationService,
44+
@IStorageService private readonly storageService: IStorageService,
45+
@IContextKeyService private readonly contextKeyService: IContextKeyService,
46+
) {
47+
super(AideChatEditorInput.EditorID, group, telemetryService, themeService, storageService);
48+
}
49+
50+
protected override createEditor(parent: HTMLElement): void {
51+
this._scopedContextKeyService = this._register(this.contextKeyService.createScoped(parent));
52+
const scopedInstantiationService = this.instantiationService.createChild(new ServiceCollection([IContextKeyService, this.scopedContextKeyService]));
53+
54+
this.widget = this._register(scopedInstantiationService.createInstance(
55+
AideChatWidget,
56+
{
57+
listForeground: editorForeground,
58+
listBackground: editorBackground,
59+
inputEditorBackground: inputBackground,
60+
resultEditorBackground: editorBackground
61+
}
62+
));
63+
this.widget.render(parent);
64+
}
65+
66+
override async setInput(input: AideChatEditorInput, options: IAideChatEditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise<void> {
67+
super.setInput(input, options, context, token);
68+
69+
const editorModel = await input.resolve();
70+
if (!editorModel) {
71+
throw new Error(`Failed to get model for chat editor. id: ${input.sessionId}`);
72+
}
73+
74+
if (!this.widget) {
75+
throw new Error('ChatEditor lifecycle issue: no editor widget');
76+
}
77+
78+
this.updateModel(editorModel.model, options?.viewState ?? input.options.viewState);
79+
}
80+
81+
private updateModel(model: IAideChatModel, viewState?: IAideChatViewState): void {
82+
this._memento = new Memento('aide-chat-editor', this.storageService);
83+
this._viewState = viewState ?? this._memento.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE) as IAideChatViewState;
84+
this.widget.setModel(model, { ...this._viewState });
85+
}
86+
87+
override layout(dimension: Dimension, position?: IDomPosition): void {
88+
if (this.widget) {
89+
this.widget.layout(dimension.height, dimension.width);
90+
}
91+
}
92+
}

0 commit comments

Comments
 (0)