@@ -10,6 +10,15 @@ import { createDecorator } from '../../../../platform/instantiation/common/insta
10
10
import { InstantiationType , registerSingleton } from '../../../../platform/instantiation/common/extensions.js' ;
11
11
import { URI } from '../../../../base/common/uri.js' ;
12
12
import { ThemeIcon } from '../../../../base/common/themables.js' ;
13
+ import { IExtensionService } from '../../../services/extensions/common/extensions.js' ;
14
+
15
+ export interface IChatSessionsExtensionPoint {
16
+ id : string ;
17
+ name : string ;
18
+ displayName : string ;
19
+ description : string ;
20
+ when ?: string ;
21
+ }
13
22
14
23
export interface IChatSessionItem {
15
24
id : string ;
@@ -27,55 +36,83 @@ export interface IChatSessionItemProvider {
27
36
28
37
export interface IChatSessionsService {
29
38
readonly _serviceBrand : undefined ;
30
- registerChatSessionItemProvider ( handle : number , provider : IChatSessionItemProvider ) : IDisposable ;
39
+ registerContribution ( contribution : IChatSessionsExtensionPoint ) : IDisposable ;
40
+ getChatSessionProviders ( ) : IChatSessionsExtensionPoint [ ] ;
41
+ registerChatSessionItemProvider ( provider : IChatSessionItemProvider ) : IDisposable ;
31
42
hasChatSessionItemProviders : boolean ;
32
- provideChatSessionItems ( token : CancellationToken ) : Promise < { provider : IChatSessionItemProvider ; session : IChatSessionItem } [ ] > ;
43
+ provideChatSessionItems ( chatSessionType : string , token : CancellationToken ) : Promise < IChatSessionItem [ ] > ;
33
44
}
34
45
35
46
export const IChatSessionsService = createDecorator < IChatSessionsService > ( 'chatSessionsService' ) ;
36
47
37
48
export class ChatSessionsService extends Disposable implements IChatSessionsService {
38
49
readonly _serviceBrand : undefined ;
39
- private _providers : Map < number , IChatSessionItemProvider > = new Map ( ) ;
50
+ private _itemsProviders : Map < string , IChatSessionItemProvider > = new Map ( ) ;
51
+ private _contributions : Map < string , IChatSessionsExtensionPoint > = new Map ( ) ;
40
52
41
53
constructor (
54
+ @IExtensionService private readonly _extensionService : IExtensionService ,
42
55
@ILogService private readonly _logService : ILogService ,
43
56
) {
44
57
super ( ) ;
45
58
}
46
59
47
- public async provideChatSessionItems ( token : CancellationToken ) : Promise < { provider : IChatSessionItemProvider ; session : IChatSessionItem } [ ] > {
48
- const results : { provider : IChatSessionItemProvider ; session : IChatSessionItem } [ ] = [ ] ;
49
-
50
- // Iterate through all registered providers and collect their results
51
- for ( const [ handle , provider ] of this . _providers ) {
52
- try {
53
- if ( provider . provideChatSessionItems ) {
54
- const sessions = await provider . provideChatSessionItems ( token ) ;
55
- results . push ( ...sessions . map ( session => ( { provider, session } ) ) ) ;
56
- }
57
- } catch ( error ) {
58
- this . _logService . error ( `Error getting chat sessions from provider ${ handle } :` , error ) ;
59
- }
60
- if ( token . isCancellationRequested ) {
61
- break ;
60
+ public registerContribution ( contribution : IChatSessionsExtensionPoint ) : IDisposable {
61
+ if ( this . _contributions . has ( contribution . id ) ) {
62
+ this . _logService . warn ( `Chat session contribution with id '${ contribution . id } ' is already registered.` ) ;
63
+ return { dispose : ( ) => { } } ;
64
+ }
65
+ this . _contributions . set ( contribution . id , contribution ) ;
66
+ // const dynamicAgentDisposable = this.registerDynamicAgent(contribution);
67
+ return {
68
+ dispose : ( ) => {
69
+ this . _contributions . delete ( contribution . id ) ;
70
+ // dynamicAgentDisposable.dispose();
62
71
}
72
+ } ;
73
+ }
74
+
75
+ getChatSessionProviders ( ) : IChatSessionsExtensionPoint [ ] {
76
+ return Array . from ( this . _contributions . values ( ) ) ;
77
+ }
78
+
79
+ async canResolve ( chatViewType : string ) {
80
+ if ( this . _itemsProviders . has ( chatViewType ) ) {
81
+ return true ;
82
+ }
83
+
84
+ await this . _extensionService . whenInstalledExtensionsRegistered ( ) ;
85
+ await this . _extensionService . activateByEvent ( `onChatSession:${ chatViewType } ` ) ;
86
+
87
+ return this . _itemsProviders . has ( chatViewType ) ;
88
+ }
89
+
90
+ public async provideChatSessionItems ( chatSessionType : string , token : CancellationToken ) : Promise < IChatSessionItem [ ] > {
91
+ if ( ! ( await this . canResolve ( chatSessionType ) ) ) {
92
+ throw Error ( `Can not find provider for ${ chatSessionType } ` ) ;
93
+ }
94
+
95
+ const provider = this . _itemsProviders . get ( chatSessionType ) ;
96
+
97
+ if ( provider ?. provideChatSessionItems ) {
98
+ const sessions = await provider . provideChatSessionItems ( token ) ;
99
+ return sessions ;
63
100
}
64
101
65
- return results ;
102
+ return [ ] ;
66
103
}
67
104
68
- public registerChatSessionItemProvider ( handle : number , provider : IChatSessionItemProvider ) : IDisposable {
69
- this . _providers . set ( handle , provider ) ;
105
+ public registerChatSessionItemProvider ( provider : IChatSessionItemProvider ) : IDisposable {
106
+ this . _itemsProviders . set ( provider . chatSessionType , provider ) ;
70
107
return {
71
108
dispose : ( ) => {
72
- this . _providers . delete ( handle ) ;
109
+ this . _itemsProviders . delete ( provider . chatSessionType ) ;
73
110
}
74
111
} ;
75
112
}
76
113
77
114
public get hasChatSessionItemProviders ( ) : boolean {
78
- return this . _providers . size > 0 ;
115
+ return this . _itemsProviders . size > 0 ;
79
116
}
80
117
}
81
118
0 commit comments