1
>
/*---------------------------------------------------------------------------------------------
chatModes.ts
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 { CancellationToken, CancellationTokenSource } from '../../../../base/common/cancellation.js';
7
>
import { Emitter, Event } from '../../../../base/common/event.js';
8
>
import { Disposable, IDisposable } from '../../../../base/common/lifecycle.js';
9
>
import { constObservable, IObservable, ISettableObservable, observableValue, transaction } from '../../../../base/common/observable.js';
10
>
import { isUriComponents, URI } from '../../../../base/common/uri.js';
11
>
import { IOffsetRange } from '../../../../editor/common/core/ranges/offsetRange.js';
12
>
import { localize } from '../../../../nls.js';
13
>
import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';
14
>
import { IContextKey, IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js';
15
>
import { ExtensionIdentifier } from '../../../../platform/extensions/common/extensions.js';
16
>
import { createDecorator, IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
17
>
import { ILogService } from '../../../../platform/log/common/log.js';
18
>
import { IStorageService, StorageScope, StorageTarget } from '../../../../platform/storage/common/storage.js';
19
>
import { IChatAgentService } from './participants/chatAgents.js';
20
>
import { ChatContextKeys } from './actions/chatContextKeys.js';
21
>
import { getChatSessionType, LocalChatSessionUri } from './model/chatUri.js';
22
>
import { ChatConfiguration, ChatModeKind } from './constants.js';
23
>
import { IHandOff } from './promptSyntax/promptFileParser.js';
24
>
import { IAgentSource, ICustomAgent, ICustomAgentVisibility, isCustomAgentVisibility, PromptsStorage } from './promptSyntax/service/promptsService.js';
25
>
import { ICustomizationHarnessService } from './customizationHarnessService.js';
26
>
import { PromptFileSource, Target } from './promptSyntax/promptTypes.js';
27
>
import { ThemeIcon } from '../../../../base/common/themables.js';
28
>
import { Codicon } from '../../../../base/common/codicons.js';
29
>
import { hash } from '../../../../base/common/hash.js';
30
>
import { isString } from '../../../../base/common/types.js';
31
>
import { isTarget } from './promptSyntax/languageProviders/promptFileAttributes.js';
32
>
import { equals as arraysEqual } from '../../../../base/common/arrays.js';
33
>
import { isEqual as isURLEquals } from '../../../../base/common/resources.js';
34
>
import { equals as objectEquals } from '../../../../base/common/objects.js';
35
>
import { Delayer } from '../../../../base/common/async.js';
36
>
import { isCancellationError } from '../../../../base/common/errors.js';
37
>
38
>
39
>
export const IChatModeService = createDecorator<IChatModeService>('chatModeService');
40
>
export interface IChatModeService {
41
>
readonly _serviceBrand: undefined;
42
>
43
>
/**
44
>
* Returns the chat modes available for the given session resource.
45
>
*
46
>
* Instances need to be disposed by the caller when no longer needed
47
>
*/
48
>
createModes(sessionResource: URI): IChatModes & IDisposable;
49
>
50
>
/**
51
>
* Returns the local chat modes after awaiting any in-flight refresh.
52
>
*/
53
>
getLocalModes(): Promise<IChatModes>;
54
>
}
55
>
56
>
/**
57
>
* The set of chat modes available for a particular session type, partitioned
58
>
* into builtin and custom modes, with helpers for lookup by id or name.
59
>
*/
60
>
export interface IChatModes {
61
>
readonly onDidChange: Event<void>;
62
>
readonly builtin: readonly IChatMode[];
63
>
readonly custom: readonly IChatMode[];
64
>
findModeById(id: string): IChatMode | undefined;
65
>
findModeByName(name: string): IChatMode | undefined;
66
>
67
>
/**
68
>
* Awaits the most recently scheduled update of custom prompt modes.
69
>
* After this resolves, {@link custom} reflects the latest data from the
70
>
* prompts service.
71
>
*/
72
>
waitForPendingUpdates(): Promise<void>;
73
>
}
74
>
75
>
class ChatModes extends Disposable implements IChatModes {
76
>
77
>
private static readonly CUSTOM_MODES_STORAGE_KEY_PREFIX = 'chat.customModes.';
78
>
79
>
private readonly hasCustomModes: IContextKey<boolean>;
80
>
private readonly _customModeInstances = new Map<string, CustomChatMode>();
81
>
private readonly _storageKey: string;
82
>
83
>
private readonly _onDidChange = this._register(new Emitter<void>());
84
>
readonly onDidChange = this._onDidChange.event;
85
>
86
>
/** Tracks the most recent refresh of custom prompt modes. */
87
>
private _pendingRefresh: Promise<void> = Promise.resolve();
88
>
89
>
private _refreshCancellationSource: CancellationTokenSource | undefined;
90
>
private readonly _refreshThrottler = this._register(new Delayer<void>(100));
91
>
92
>
constructor(
93
private readonly sessionResource: URI,
94
@IChatAgentService private readonly chatAgentService: IChatAgentService,