diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionServiceImpl.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionServiceImpl.ts index 849200791db..84f6c67fe09 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionServiceImpl.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionServiceImpl.ts @@ -36,6 +36,7 @@ import { nullExtensionDescription } from 'vs/workbench/services/extensions/commo import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/untitledTextEditorInput'; import { EmptyResponse, ErrorResponse, HunkData, ReplyResponse, Session, SessionExchange, SessionWholeRange, StashedSession, TelemetryData, TelemetryDataClassification } from './inlineChatSession'; import { IInlineChatSessionEndEvent, IInlineChatSessionEvent, IInlineChatSessionService, ISessionKeyComputer, Recording } from './inlineChatSessionService'; +import { IChatVariablesService } from 'vs/workbench/contrib/chat/common/chatVariables'; class BridgeAgent implements IChatAgentImplementation { @@ -70,12 +71,15 @@ class BridgeAgent implements IChatAgentImplementation { throw new Error('FAILED to find session'); } - const { session, editor } = data; + const { session } = data; if (!session.lastInput) { throw new Error('FAILED to find last input'); } + const inlineChatContextValue = request.variables.variables.find(candidate => candidate.name === _inlineChatContext)?.values[0]; + const inlineChatContext = typeof inlineChatContextValue?.value === 'string' && JSON.parse(inlineChatContextValue.value); + const modelAltVersionIdNow = session.textModelN.getAlternativeVersionId(); const progressEdits: TextEdit[][] = []; @@ -86,8 +90,8 @@ class BridgeAgent implements IChatAgentImplementation { withIntentDetection: request.enableCommandDetection ?? true, live: session.editMode !== EditMode.Preview, previewDocument: session.textModelN.uri, - selection: editor.getSelection()!, - wholeRange: session.wholeRange.trackedInitialRange, + selection: inlineChatContext.selection, + wholeRange: inlineChatContext.wholeRange }; const inlineProgress = new Progress(data => { @@ -199,6 +203,7 @@ export class InlineChatError extends Error { } const _bridgeAgentId = 'brigde.editor'; +const _inlineChatContext = '_inlineChatContext'; export class InlineChatSessionServiceImpl implements IInlineChatSessionService { @@ -235,6 +240,7 @@ export class InlineChatSessionServiceImpl implements IInlineChatSessionService { @IEditorService private readonly _editorService: IEditorService, @IChatService private readonly _chatService: IChatService, @IChatAgentService private readonly _chatAgentService: IChatAgentService, + @IChatVariablesService chatVariableService: IChatVariablesService, ) { // MARK: register fake chat agent @@ -266,7 +272,7 @@ export class InlineChatSessionServiceImpl implements IInlineChatSessionService { } satisfies IChatAgentCommand; }); }, - defaultImplicitVariables: [], + defaultImplicitVariables: [_inlineChatContext], metadata: { isSticky: false, themeIcon: Codicon.copilot, @@ -298,6 +304,28 @@ export class InlineChatSessionServiceImpl implements IInlineChatSessionService { this._store.add(this._chatAgentService.onDidChangeAgents(() => addOrRemoveBridgeAgent())); const brigdeAgent = this._store.add(new MutableDisposable()); addOrRemoveBridgeAgent(); + + + // MARK: implicit variable for editor selection and (tracked) whole range + + this._store.add(chatVariableService.registerVariable( + { name: _inlineChatContext, description: '', hidden: true }, + async (_message, _arg, model) => { + for (const [, data] of this._sessions) { + if (data.session.chatModel === model) { + return [{ + level: 'full', + value: JSON.stringify({ + selection: data.editor.getSelection(), + wholeRange: data.session.wholeRange.trackedInitialRange + }) + }]; + } + } + return undefined; + } + )); + } dispose() { diff --git a/src/vs/workbench/contrib/inlineChat/test/browser/inlineChatController.test.ts b/src/vs/workbench/contrib/inlineChat/test/browser/inlineChatController.test.ts index b1cdcf53221..5b1528d3604 100644 --- a/src/vs/workbench/contrib/inlineChat/test/browser/inlineChatController.test.ts +++ b/src/vs/workbench/contrib/inlineChat/test/browser/inlineChatController.test.ts @@ -47,7 +47,6 @@ import { IExtensionService, nullExtensionDescription } from 'vs/workbench/servic import { IChatService } from 'vs/workbench/contrib/chat/common/chatService'; import { ChatService } from 'vs/workbench/contrib/chat/common/chatServiceImpl'; import { IChatVariablesService } from 'vs/workbench/contrib/chat/common/chatVariables'; -import { MockChatVariablesService } from 'vs/workbench/contrib/chat/test/common/mockChatVariables'; import { ILogService, NullLogService } from 'vs/platform/log/common/log'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; @@ -59,6 +58,7 @@ import { ChatWidgetService } from 'vs/workbench/contrib/chat/browser/chatWidget' import { ChatWidgetHistoryService, IChatWidgetHistoryService } from 'vs/workbench/contrib/chat/common/chatWidgetHistoryService'; import { IHoverService } from 'vs/platform/hover/browser/hover'; import { NullHoverService } from 'vs/platform/hover/test/browser/nullHoverService'; +import { ChatVariablesService } from 'vs/workbench/contrib/chat/browser/chatVariables'; suite('InteractiveChatController', function () { class TestController extends InlineChatController { @@ -119,7 +119,7 @@ suite('InteractiveChatController', function () { const serviceCollection = new ServiceCollection( [IConfigurationService, new TestConfigurationService()], - [IChatVariablesService, new MockChatVariablesService()], + [IChatVariablesService, new SyncDescriptor(ChatVariablesService)], [ILogService, new NullLogService()], [ITelemetryService, NullTelemetryService], [IHoverService, NullHoverService], diff --git a/src/vs/workbench/contrib/inlineChat/test/browser/inlineChatSession.test.ts b/src/vs/workbench/contrib/inlineChat/test/browser/inlineChatSession.test.ts index e2dc5ae92db..b362b16f002 100644 --- a/src/vs/workbench/contrib/inlineChat/test/browser/inlineChatSession.test.ts +++ b/src/vs/workbench/contrib/inlineChat/test/browser/inlineChatSession.test.ts @@ -51,10 +51,10 @@ import { ChatService } from 'vs/workbench/contrib/chat/common/chatServiceImpl'; import { IChatSlashCommandService, ChatSlashCommandService } from 'vs/workbench/contrib/chat/common/chatSlashCommands'; import { IChatVariablesService } from 'vs/workbench/contrib/chat/common/chatVariables'; import { IChatWidgetHistoryService, ChatWidgetHistoryService } from 'vs/workbench/contrib/chat/common/chatWidgetHistoryService'; -import { MockChatVariablesService } from 'vs/workbench/contrib/chat/test/common/mockChatVariables'; import { IViewsService } from 'vs/workbench/services/views/common/viewsService'; import { TestExtensionService, TestContextService } from 'vs/workbench/test/common/workbenchTestServices'; import { IChatAgentService, ChatAgentService, ChatAgentLocation } from 'vs/workbench/contrib/chat/common/chatAgents'; +import { ChatVariablesService } from 'vs/workbench/contrib/chat/browser/chatVariables'; suite('InlineChatSession', function () { @@ -72,7 +72,7 @@ suite('InlineChatSession', function () { const serviceCollection = new ServiceCollection( [IConfigurationService, new TestConfigurationService()], - [IChatVariablesService, new MockChatVariablesService()], + [IChatVariablesService, new SyncDescriptor(ChatVariablesService)], [ILogService, new NullLogService()], [ITelemetryService, NullTelemetryService], [IExtensionService, new TestExtensionService()],