@codingame/monaco-vscode-mcp-service-override 17.2.0 → 18.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +20 -2
- package/package.json +14 -5
- package/vscode/src/vs/platform/mcp/common/mcpGalleryService.d.ts +26 -0
- package/vscode/src/vs/platform/mcp/common/mcpGalleryService.js +170 -0
- package/vscode/src/vs/platform/mcp/common/mcpManagementService.d.ts +35 -0
- package/vscode/src/vs/platform/mcp/common/mcpManagementService.js +292 -0
- package/vscode/src/vs/platform/mcp/common/mcpPlatformTypes.d.ts +65 -0
- package/vscode/src/vs/platform/mcp/common/mcpPlatformTypes.js +9 -0
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcp.contribution.js +64 -5
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpAddContextContribution.d.ts +12 -0
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpAddContextContribution.js +76 -0
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpDiscovery.js +2 -2
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpLanguageFeatures.js +73 -27
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerActions.d.ts +106 -0
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerActions.js +423 -0
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerEditor.d.ts +61 -0
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerEditor.js +542 -0
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerEditorInput.d.ts +17 -0
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerEditorInput.js +45 -0
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerWidgets.d.ts +54 -0
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerWidgets.js +272 -0
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServersView.d.ts +24 -0
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServersView.js +193 -0
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpWorkbenchService.d.ts +56 -0
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpWorkbenchService.js +176 -0
- package/vscode/src/vs/workbench/contrib/mcp/common/discovery/configMcpDiscovery.d.ts +3 -1
- package/vscode/src/vs/workbench/contrib/mcp/common/discovery/configMcpDiscovery.js +27 -6
- package/vscode/src/vs/workbench/contrib/mcp/common/discovery/extensionMcpDiscovery.js +8 -6
- package/vscode/src/vs/workbench/contrib/mcp/common/discovery/nativeMcpDiscoveryAbstract.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/mcp/common/discovery/nativeMcpDiscoveryAbstract.js +6 -4
- package/vscode/src/vs/workbench/contrib/mcp/common/discovery/nativeMcpDiscoveryAdapters.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/mcp/common/discovery/nativeMcpDiscoveryAdapters.js +2 -2
- package/vscode/src/vs/workbench/contrib/mcp/common/discovery/workspaceMcpDiscoveryAdapter.js +4 -2
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpConfigPathsService.js +4 -4
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpDevMode.d.ts +23 -0
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpDevMode.js +89 -0
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpDevMode.service.d.ts +6 -0
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpDevMode.service.js +6 -0
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpRegistry.d.ts +8 -6
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpRegistry.js +30 -47
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpResourceFilesystem.d.ts +35 -0
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpResourceFilesystem.js +206 -0
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpSamplingLog.d.ts +26 -0
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpSamplingLog.js +110 -0
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpSamplingService.d.ts +38 -0
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpSamplingService.js +256 -0
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpServer.d.ts +29 -13
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpServer.js +313 -116
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpServerConnection.d.ts +2 -2
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpServerConnection.js +15 -17
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpServerRequestHandler.d.ts +16 -7
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpServerRequestHandler.js +58 -39
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpService.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpService.js +109 -46
- package/vscode/src/vs/workbench/contrib/mcp/common/uriTemplate.d.ts +25 -0
- package/vscode/src/vs/workbench/contrib/mcp/common/uriTemplate.js +296 -0
- package/vscode/src/vs/workbench/services/authentication/browser/authenticationMcpAccessService.d.ts +27 -0
- package/vscode/src/vs/workbench/services/authentication/browser/authenticationMcpAccessService.js +73 -0
- package/vscode/src/vs/workbench/services/authentication/browser/authenticationMcpService.d.ts +51 -0
- package/vscode/src/vs/workbench/services/authentication/browser/authenticationMcpService.js +391 -0
- package/vscode/src/vs/workbench/services/authentication/browser/authenticationMcpUsageService.d.ts +27 -0
- package/vscode/src/vs/workbench/services/authentication/browser/authenticationMcpUsageService.js +105 -0
- package/vscode/src/vs/workbench/contrib/mcp/common/modelContextProtocol.d.ts +0 -395
- package/vscode/src/vs/workbench/contrib/mcp/common/modelContextProtocol.js +0 -14
|
@@ -14,7 +14,7 @@ import { IResolvedValue } from "@codingame/monaco-vscode-api/vscode/vs/workbench
|
|
|
14
14
|
import { IEditorService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/editor/common/editorService.service";
|
|
15
15
|
import { IMcpHostDelegate, IMcpResolveConnectionOptions } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpRegistryTypes";
|
|
16
16
|
import { IMcpRegistry } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpRegistryTypes.service";
|
|
17
|
-
import { IMcpServerConnection, LazyCollectionState, McpCollectionDefinition, McpCollectionReference } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypes";
|
|
17
|
+
import { IMcpServerConnection, LazyCollectionState, McpCollectionDefinition, McpCollectionReference, McpDefinitionReference, McpServerDefinition } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypes";
|
|
18
18
|
export declare class McpRegistry extends Disposable implements IMcpRegistry {
|
|
19
19
|
private readonly _instantiationService;
|
|
20
20
|
private readonly _configurationResolverService;
|
|
@@ -29,19 +29,21 @@ export declare class McpRegistry extends Disposable implements IMcpRegistry {
|
|
|
29
29
|
private readonly _delegates;
|
|
30
30
|
private readonly _enabled;
|
|
31
31
|
readonly collections: IObservable<readonly McpCollectionDefinition[]>;
|
|
32
|
-
private readonly _collectionToPrefixes;
|
|
33
32
|
private readonly _workspaceStorage;
|
|
34
33
|
private readonly _profileStorage;
|
|
35
34
|
private readonly _trustMemento;
|
|
36
35
|
private readonly _ongoingLazyActivations;
|
|
37
|
-
readonly lazyCollectionState:
|
|
38
|
-
get delegates(): readonly IMcpHostDelegate[]
|
|
36
|
+
readonly lazyCollectionState: import("@codingame/monaco-vscode-api/vscode/vs/base/common/observable").IObservableWithChange<LazyCollectionState, void>;
|
|
37
|
+
get delegates(): IObservable<readonly IMcpHostDelegate[]>;
|
|
39
38
|
private readonly _onDidChangeInputs;
|
|
40
39
|
readonly onDidChangeInputs: import("@codingame/monaco-vscode-api/vscode/vs/base/common/event").Event<void>;
|
|
41
40
|
constructor(_instantiationService: IInstantiationService, _configurationResolverService: IConfigurationResolverService, _dialogService: IDialogService, _storageService: IStorageService, _productService: IProductService, _notificationService: INotificationService, _editorService: IEditorService, configurationService: IConfigurationService);
|
|
42
41
|
registerDelegate(delegate: IMcpHostDelegate): IDisposable;
|
|
43
42
|
registerCollection(collection: McpCollectionDefinition): IDisposable;
|
|
44
|
-
|
|
43
|
+
getServerDefinition(collectionRef: McpDefinitionReference, definitionRef: McpDefinitionReference): IObservable<{
|
|
44
|
+
server: McpServerDefinition | undefined;
|
|
45
|
+
collection: McpCollectionDefinition | undefined;
|
|
46
|
+
}>;
|
|
45
47
|
discoverCollections(): Promise<McpCollectionDefinition[]>;
|
|
46
48
|
private _getInputStorage;
|
|
47
49
|
private _getInputStorageInConfigTarget;
|
|
@@ -57,5 +59,5 @@ export declare class McpRegistry extends Disposable implements IMcpRegistry {
|
|
|
57
59
|
private _promptForTrustOpenDialog;
|
|
58
60
|
private _updateStorageWithExpressionInputs;
|
|
59
61
|
private _replaceVariablesInLaunch;
|
|
60
|
-
resolveConnection({ collectionRef, definitionRef, forceTrust, logger }: IMcpResolveConnectionOptions): Promise<IMcpServerConnection | undefined>;
|
|
62
|
+
resolveConnection({ collectionRef, definitionRef, forceTrust, logger, debug }: IMcpResolveConnectionOptions): Promise<IMcpServerConnection | undefined>;
|
|
61
63
|
}
|
|
@@ -2,13 +2,11 @@
|
|
|
2
2
|
import { __decorate, __param } from '@codingame/monaco-vscode-api/external/tslib/tslib.es6';
|
|
3
3
|
import { Codicon } from '@codingame/monaco-vscode-api/vscode/vs/base/common/codicons';
|
|
4
4
|
import { Emitter } from '@codingame/monaco-vscode-api/vscode/vs/base/common/event';
|
|
5
|
-
import { StringSHA1 } from '@codingame/monaco-vscode-api/vscode/vs/base/common/hash';
|
|
6
5
|
import { MarkdownString } from '@codingame/monaco-vscode-api/vscode/vs/base/common/htmlContent';
|
|
7
6
|
import { Lazy } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lazy';
|
|
8
7
|
import { Disposable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
|
|
9
8
|
import '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/index';
|
|
10
9
|
import { basename } from '@codingame/monaco-vscode-api/vscode/vs/base/common/resources';
|
|
11
|
-
import { indexOfPattern } from '@codingame/monaco-vscode-api/vscode/vs/base/common/strings';
|
|
12
10
|
import { localize } from '@codingame/monaco-vscode-api/vscode/vs/nls';
|
|
13
11
|
import { ConfigurationTarget } from '@codingame/monaco-vscode-api/vscode/vs/platform/configuration/common/configuration';
|
|
14
12
|
import { IConfigurationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/configuration/common/configuration.service';
|
|
@@ -25,19 +23,19 @@ import { IConfigurationResolverService } from '@codingame/monaco-vscode-api/vsco
|
|
|
25
23
|
import { ConfigurationResolverExpression } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/configurationResolver/common/configurationResolverExpression';
|
|
26
24
|
import { AUX_WINDOW_GROUP } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/editor/common/editorService';
|
|
27
25
|
import { IEditorService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/editor/common/editorService.service';
|
|
28
|
-
import { mcpEnabledSection } from '@codingame/monaco-vscode-
|
|
26
|
+
import { mcpEnabledSection } from '@codingame/monaco-vscode-aa9ead53-dfd3-59da-b9e7-f163d201de8d-common/vscode/vs/workbench/contrib/mcp/common/mcpConfiguration';
|
|
27
|
+
import { IMcpDevModeDebugging } from './mcpDevMode.service.js';
|
|
29
28
|
import { McpRegistryInputStorage } from './mcpRegistryInputStorage.js';
|
|
30
29
|
import { McpServerConnection } from './mcpServerConnection.js';
|
|
31
30
|
import { LazyCollectionState } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypes';
|
|
32
31
|
import Severity from '@codingame/monaco-vscode-api/vscode/vs/base/common/severity';
|
|
33
|
-
import { observableValue } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/
|
|
34
|
-
import { derived } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/derived';
|
|
32
|
+
import { observableValue } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/observableValue';
|
|
33
|
+
import { derived } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/derived';
|
|
35
34
|
|
|
36
35
|
const createTrustMemento = observableMemento({
|
|
37
36
|
defaultValue: {},
|
|
38
37
|
key: 'mcp.trustedCollections'
|
|
39
38
|
});
|
|
40
|
-
const collectionPrefixLen = 3;
|
|
41
39
|
let McpRegistry = class McpRegistry extends Disposable {
|
|
42
40
|
get delegates() {
|
|
43
41
|
return this._delegates;
|
|
@@ -53,36 +51,13 @@ let McpRegistry = class McpRegistry extends Disposable {
|
|
|
53
51
|
this._editorService = _editorService;
|
|
54
52
|
this._trustPrompts = ( new Map());
|
|
55
53
|
this._collections = observableValue('collections', []);
|
|
56
|
-
this._delegates = [];
|
|
54
|
+
this._delegates = observableValue('delegates', []);
|
|
57
55
|
this.collections = derived(reader => {
|
|
58
56
|
if (!this._enabled.read(reader)) {
|
|
59
57
|
return [];
|
|
60
58
|
}
|
|
61
59
|
return this._collections.read(reader);
|
|
62
60
|
});
|
|
63
|
-
this._collectionToPrefixes = ( this._collections.map(c => {
|
|
64
|
-
const hashes = ( c.map((collection) => {
|
|
65
|
-
const sha = ( new StringSHA1());
|
|
66
|
-
sha.update(collection.id);
|
|
67
|
-
const hash = sha.digest();
|
|
68
|
-
return { view: indexOfPattern(hash, /[a-z]/i), hash, collection };
|
|
69
|
-
}));
|
|
70
|
-
const view = (h) => h.hash.slice(h.view, h.view + collectionPrefixLen);
|
|
71
|
-
let collided = false;
|
|
72
|
-
do {
|
|
73
|
-
hashes.sort((a, b) => view(a).localeCompare(view(b)) || a.collection.id.localeCompare(b.collection.id));
|
|
74
|
-
collided = false;
|
|
75
|
-
for (let i = 1; i < hashes.length; i++) {
|
|
76
|
-
const prev = hashes[i - 1];
|
|
77
|
-
const curr = hashes[i];
|
|
78
|
-
if (view(prev) === view(curr) && curr.view + collectionPrefixLen < curr.hash.length) {
|
|
79
|
-
curr.view++;
|
|
80
|
-
collided = true;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
} while (collided);
|
|
84
|
-
return Object.fromEntries(( hashes.map(h => [h.collection.id, view(h) + '.'])));
|
|
85
|
-
}));
|
|
86
61
|
this._workspaceStorage = ( new Lazy(
|
|
87
62
|
() => this._register(this._instantiationService.createInstance(McpRegistryInputStorage, StorageScope.WORKSPACE, StorageTarget.USER))
|
|
88
63
|
));
|
|
@@ -108,14 +83,14 @@ let McpRegistry = class McpRegistry extends Disposable {
|
|
|
108
83
|
this._enabled = observableConfigValue(mcpEnabledSection, true, configurationService);
|
|
109
84
|
}
|
|
110
85
|
registerDelegate(delegate) {
|
|
111
|
-
this._delegates.
|
|
112
|
-
|
|
86
|
+
const delegates = this._delegates.get().slice();
|
|
87
|
+
delegates.push(delegate);
|
|
88
|
+
delegates.sort((a, b) => b.priority - a.priority);
|
|
89
|
+
this._delegates.set(delegates, undefined);
|
|
113
90
|
return {
|
|
114
91
|
dispose: () => {
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
this._delegates.splice(index, 1);
|
|
118
|
-
}
|
|
92
|
+
const delegates = this._delegates.get().filter(d => d !== delegate);
|
|
93
|
+
this._delegates.set(delegates, undefined);
|
|
119
94
|
}
|
|
120
95
|
};
|
|
121
96
|
}
|
|
@@ -126,7 +101,8 @@ let McpRegistry = class McpRegistry extends Disposable {
|
|
|
126
101
|
this._collections.set(( currentCollections.map(c => c === toReplace ? collection : c)), undefined);
|
|
127
102
|
}
|
|
128
103
|
else {
|
|
129
|
-
this._collections.set([...currentCollections, collection]
|
|
104
|
+
this._collections.set([...currentCollections, collection]
|
|
105
|
+
.sort((a, b) => (a.presentation?.order || 0) - (b.presentation?.order || 0)), undefined);
|
|
130
106
|
}
|
|
131
107
|
return {
|
|
132
108
|
dispose: () => {
|
|
@@ -135,8 +111,12 @@ let McpRegistry = class McpRegistry extends Disposable {
|
|
|
135
111
|
}
|
|
136
112
|
};
|
|
137
113
|
}
|
|
138
|
-
|
|
139
|
-
|
|
114
|
+
getServerDefinition(collectionRef, definitionRef) {
|
|
115
|
+
const collectionObs = ( this._collections.map(cols => cols.find(c => c.id === collectionRef.id)));
|
|
116
|
+
return ( collectionObs.map((collection, reader) => {
|
|
117
|
+
const server = collection?.serverDefinitions.read(reader).find(s => s.id === definitionRef.id);
|
|
118
|
+
return { collection, server };
|
|
119
|
+
}));
|
|
140
120
|
}
|
|
141
121
|
async discoverCollections() {
|
|
142
122
|
const toDiscover = this._collections.get().filter(c => c.lazy && !c.lazy.isCached);
|
|
@@ -221,12 +201,12 @@ let McpRegistry = class McpRegistry extends Disposable {
|
|
|
221
201
|
const originURI = collection.presentation?.origin;
|
|
222
202
|
const labelWithOrigin = originURI ? `[\`${basename(originURI)}\`](${originURI})` : collection.label;
|
|
223
203
|
const result = await this._dialogService.prompt({
|
|
224
|
-
message: ( localize(
|
|
204
|
+
message: ( localize(7950, 'Trust MCP servers from {0}?', collection.label)),
|
|
225
205
|
custom: {
|
|
226
206
|
icon: Codicon.shield,
|
|
227
207
|
markdownDetails: [{
|
|
228
208
|
markdown: ( new MarkdownString(( localize(
|
|
229
|
-
|
|
209
|
+
7951,
|
|
230
210
|
'{0} discovered Model Context Protocol servers from {1} (`{2}`). {0} can use their capabilities in Chat.\n\nDo you want to allow running MCP servers from {3}?',
|
|
231
211
|
this._productService.nameShort,
|
|
232
212
|
collection.label,
|
|
@@ -240,8 +220,8 @@ let McpRegistry = class McpRegistry extends Disposable {
|
|
|
240
220
|
}]
|
|
241
221
|
},
|
|
242
222
|
buttons: [
|
|
243
|
-
{ label: ( localize(
|
|
244
|
-
{ label: ( localize(
|
|
223
|
+
{ label: ( localize(7952, 'Trust')), run: () => true },
|
|
224
|
+
{ label: ( localize(7953, 'Do not trust')), run: () => false }
|
|
245
225
|
],
|
|
246
226
|
});
|
|
247
227
|
return result.result;
|
|
@@ -278,7 +258,7 @@ let McpRegistry = class McpRegistry extends Disposable {
|
|
|
278
258
|
await this._updateStorageWithExpressionInputs(inputStorage, expr);
|
|
279
259
|
return await this._configurationResolverService.resolveAsync(folder, expr);
|
|
280
260
|
}
|
|
281
|
-
async resolveConnection({ collectionRef, definitionRef, forceTrust, logger }) {
|
|
261
|
+
async resolveConnection({ collectionRef, definitionRef, forceTrust, logger, debug }) {
|
|
282
262
|
let collection = this._collections.get().find(c => c.id === collectionRef.id);
|
|
283
263
|
if (collection?.lazy) {
|
|
284
264
|
await collection.lazy.load();
|
|
@@ -290,7 +270,7 @@ let McpRegistry = class McpRegistry extends Disposable {
|
|
|
290
270
|
`Collection or definition not found for ${collectionRef.id} and ${definitionRef.id}`
|
|
291
271
|
));
|
|
292
272
|
}
|
|
293
|
-
const delegate = this._delegates.find(d => d.canStart(collection, definition));
|
|
273
|
+
const delegate = this._delegates.get().find(d => d.canStart(collection, definition));
|
|
294
274
|
if (!delegate) {
|
|
295
275
|
throw ( new Error('No delegate found that can handle the connection'));
|
|
296
276
|
}
|
|
@@ -320,11 +300,14 @@ let McpRegistry = class McpRegistry extends Disposable {
|
|
|
320
300
|
}
|
|
321
301
|
try {
|
|
322
302
|
launch = await this._replaceVariablesInLaunch(definition, launch);
|
|
303
|
+
if (definition.devMode && debug) {
|
|
304
|
+
launch = await this._instantiationService.invokeFunction(accessor => accessor.get(IMcpDevModeDebugging).transform(definition, launch));
|
|
305
|
+
}
|
|
323
306
|
}
|
|
324
307
|
catch (e) {
|
|
325
308
|
this._notificationService.notify({
|
|
326
309
|
severity: Severity.Error,
|
|
327
|
-
message: ( localize(
|
|
310
|
+
message: ( localize(7954, 'Error starting {0}: {1}', definition.label, String(e))),
|
|
328
311
|
actions: {
|
|
329
312
|
primary: collection.presentation?.origin && [
|
|
330
313
|
{
|
|
@@ -332,7 +315,7 @@ let McpRegistry = class McpRegistry extends Disposable {
|
|
|
332
315
|
class: undefined,
|
|
333
316
|
enabled: true,
|
|
334
317
|
tooltip: '',
|
|
335
|
-
label: ( localize(
|
|
318
|
+
label: ( localize(7955, 'Open Configuration')),
|
|
336
319
|
run: () => this._editorService.openEditor({
|
|
337
320
|
resource: collection.presentation.origin,
|
|
338
321
|
options: { selection: definition.presentation?.origin?.range }
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { CancellationToken } from "@codingame/monaco-vscode-api/vscode/vs/base/common/cancellation";
|
|
2
|
+
import { Event } from "@codingame/monaco-vscode-api/vscode/vs/base/common/event";
|
|
3
|
+
import { Disposable, IDisposable } from "@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle";
|
|
4
|
+
import { ReadableStreamEvents } from "@codingame/monaco-vscode-api/vscode/vs/base/common/stream";
|
|
5
|
+
import { URI } from "@codingame/monaco-vscode-api/vscode/vs/base/common/uri";
|
|
6
|
+
import { FileSystemProviderCapabilities, FileType, IFileChange, IFileDeleteOptions, IFileOverwriteOptions, IFileReadStreamOptions, IFileSystemProviderWithFileAtomicReadCapability, IFileSystemProviderWithFileReadStreamCapability, IFileSystemProviderWithFileReadWriteCapability, IFileWriteOptions, IStat, IWatchOptions } from "@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files";
|
|
7
|
+
import { IFileService } from "@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files.service";
|
|
8
|
+
import { IInstantiationService } from "@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation";
|
|
9
|
+
import { IWorkbenchContribution } from "@codingame/monaco-vscode-api/vscode/vs/workbench/common/contributions";
|
|
10
|
+
export declare class McpResourceFilesystem extends Disposable implements IWorkbenchContribution, IFileSystemProviderWithFileReadWriteCapability, IFileSystemProviderWithFileAtomicReadCapability, IFileSystemProviderWithFileReadStreamCapability {
|
|
11
|
+
private readonly _instantiationService;
|
|
12
|
+
private readonly _fileService;
|
|
13
|
+
private readonly _mcpServiceLazy;
|
|
14
|
+
private get _mcpService();
|
|
15
|
+
readonly onDidChangeCapabilities: Event<any>;
|
|
16
|
+
private readonly _onDidChangeFile;
|
|
17
|
+
readonly onDidChangeFile: Event<readonly IFileChange[]>;
|
|
18
|
+
readonly capabilities: FileSystemProviderCapabilities;
|
|
19
|
+
constructor(_instantiationService: IInstantiationService, _fileService: IFileService);
|
|
20
|
+
readFile(resource: URI): Promise<Uint8Array>;
|
|
21
|
+
readFileStream(resource: URI, opts: IFileReadStreamOptions, token: CancellationToken): ReadableStreamEvents<Uint8Array>;
|
|
22
|
+
watch(uri: URI, _opts: IWatchOptions): IDisposable;
|
|
23
|
+
stat(resource: URI): Promise<IStat>;
|
|
24
|
+
readdir(resource: URI): Promise<[
|
|
25
|
+
string,
|
|
26
|
+
FileType
|
|
27
|
+
][]>;
|
|
28
|
+
mkdir(resource: URI): Promise<void>;
|
|
29
|
+
writeFile(resource: URI, content: Uint8Array, opts: IFileWriteOptions): Promise<void>;
|
|
30
|
+
delete(resource: URI, opts: IFileDeleteOptions): Promise<void>;
|
|
31
|
+
rename(from: URI, to: URI, opts: IFileOverwriteOptions): Promise<void>;
|
|
32
|
+
private _readFile;
|
|
33
|
+
private _decodeURI;
|
|
34
|
+
private _readURI;
|
|
35
|
+
}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
|
|
2
|
+
import { __decorate, __param } from '@codingame/monaco-vscode-api/external/tslib/tslib.es6';
|
|
3
|
+
import { sumBy } from '@codingame/monaco-vscode-api/vscode/vs/base/common/arrays';
|
|
4
|
+
import { VSBuffer, decodeBase64 } from '@codingame/monaco-vscode-api/vscode/vs/base/common/buffer';
|
|
5
|
+
import { CancellationTokenSource } from '@codingame/monaco-vscode-api/vscode/vs/base/common/cancellation';
|
|
6
|
+
import { Event, Emitter } from '@codingame/monaco-vscode-api/vscode/vs/base/common/event';
|
|
7
|
+
import { Lazy } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lazy';
|
|
8
|
+
import { Disposable, DisposableStore, MutableDisposable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
|
|
9
|
+
import '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/index';
|
|
10
|
+
import { newWriteableStream } from '@codingame/monaco-vscode-api/vscode/vs/base/common/stream';
|
|
11
|
+
import { equalsIgnoreCase } from '@codingame/monaco-vscode-api/vscode/vs/base/common/strings';
|
|
12
|
+
import { URI } from '@codingame/monaco-vscode-api/vscode/vs/base/common/uri';
|
|
13
|
+
import { FileSystemProviderCapabilities, FileChangeType, createFileSystemProviderError, FileSystemProviderErrorCode, FileType } from '@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files';
|
|
14
|
+
import { IFileService } from '@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files.service';
|
|
15
|
+
import { IInstantiationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation';
|
|
16
|
+
import { McpServer } from './mcpServer.js';
|
|
17
|
+
import { McpResourceURI, McpCapability } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypes';
|
|
18
|
+
import { IMcpService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypes.service';
|
|
19
|
+
import { autorun } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/reactions/autorun';
|
|
20
|
+
|
|
21
|
+
let McpResourceFilesystem = class McpResourceFilesystem extends Disposable {
|
|
22
|
+
get _mcpService() {
|
|
23
|
+
return this._mcpServiceLazy.value;
|
|
24
|
+
}
|
|
25
|
+
constructor(_instantiationService, _fileService) {
|
|
26
|
+
super();
|
|
27
|
+
this._instantiationService = _instantiationService;
|
|
28
|
+
this._fileService = _fileService;
|
|
29
|
+
this._mcpServiceLazy = ( new Lazy(() => this._instantiationService.invokeFunction(a => a.get(IMcpService))));
|
|
30
|
+
this.onDidChangeCapabilities = Event.None;
|
|
31
|
+
this._onDidChangeFile = this._register(( new Emitter()));
|
|
32
|
+
this.onDidChangeFile = this._onDidChangeFile.event;
|
|
33
|
+
this.capabilities = FileSystemProviderCapabilities.None
|
|
34
|
+
| FileSystemProviderCapabilities.Readonly
|
|
35
|
+
| FileSystemProviderCapabilities.PathCaseSensitive
|
|
36
|
+
| FileSystemProviderCapabilities.FileReadStream
|
|
37
|
+
| FileSystemProviderCapabilities.FileAtomicRead
|
|
38
|
+
| FileSystemProviderCapabilities.FileReadWrite;
|
|
39
|
+
this._register(this._fileService.registerProvider(McpResourceURI.scheme, this));
|
|
40
|
+
}
|
|
41
|
+
async readFile(resource) {
|
|
42
|
+
return this._readFile(resource);
|
|
43
|
+
}
|
|
44
|
+
readFileStream(resource, opts, token) {
|
|
45
|
+
const stream = newWriteableStream(data => VSBuffer.concat(( data.map(data => VSBuffer.wrap(data)))).buffer);
|
|
46
|
+
this._readFile(resource, token).then(data => {
|
|
47
|
+
if (opts.position) {
|
|
48
|
+
data = data.slice(opts.position);
|
|
49
|
+
}
|
|
50
|
+
if (opts.length) {
|
|
51
|
+
data = data.slice(0, opts.length);
|
|
52
|
+
}
|
|
53
|
+
stream.end(data);
|
|
54
|
+
}, err => stream.error(err));
|
|
55
|
+
return stream;
|
|
56
|
+
}
|
|
57
|
+
watch(uri, _opts) {
|
|
58
|
+
const { resourceURI, server } = this._decodeURI(uri);
|
|
59
|
+
const cap = server.capabilities.get();
|
|
60
|
+
if (cap !== undefined && !(cap & McpCapability.ResourcesSubscribe)) {
|
|
61
|
+
return Disposable.None;
|
|
62
|
+
}
|
|
63
|
+
server.start();
|
|
64
|
+
const store = ( new DisposableStore());
|
|
65
|
+
let watchedOnHandler;
|
|
66
|
+
const watchListener = store.add(( new MutableDisposable()));
|
|
67
|
+
const callCts = store.add(( new MutableDisposable()));
|
|
68
|
+
store.add(autorun(reader => {
|
|
69
|
+
const connection = server.connection.read(reader);
|
|
70
|
+
if (!connection) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const handler = connection.handler.read(reader);
|
|
74
|
+
if (!handler || watchedOnHandler === handler) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
callCts.value?.dispose(true);
|
|
78
|
+
callCts.value = ( new CancellationTokenSource());
|
|
79
|
+
watchedOnHandler = handler;
|
|
80
|
+
const token = callCts.value.token;
|
|
81
|
+
handler.subscribe({ uri: ( resourceURI.toString(true)) }, token).then(() => {
|
|
82
|
+
if (!token.isCancellationRequested) {
|
|
83
|
+
watchListener.value = handler.onDidUpdateResource(e => {
|
|
84
|
+
if (equalsUriPath(e.params.uri, resourceURI)) {
|
|
85
|
+
this._onDidChangeFile.fire([{ resource: uri, type: FileChangeType.UPDATED }]);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}, err => {
|
|
90
|
+
handler.logger.warn(`Failed to subscribe to resource changes for ${resourceURI}: ${err}`);
|
|
91
|
+
watchedOnHandler = undefined;
|
|
92
|
+
});
|
|
93
|
+
}));
|
|
94
|
+
return store;
|
|
95
|
+
}
|
|
96
|
+
async stat(resource) {
|
|
97
|
+
const { forSameURI, contents } = await this._readURI(resource);
|
|
98
|
+
if (!contents.length) {
|
|
99
|
+
throw createFileSystemProviderError(`File not found`, FileSystemProviderErrorCode.FileNotFound);
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
ctime: 0,
|
|
103
|
+
mtime: 0,
|
|
104
|
+
size: sumBy(contents, c => contentToBuffer(c).byteLength),
|
|
105
|
+
type: forSameURI.length ? FileType.File : FileType.Directory,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
async readdir(resource) {
|
|
109
|
+
const { forSameURI, contents, resourceURI } = await this._readURI(resource);
|
|
110
|
+
if (forSameURI.length > 0) {
|
|
111
|
+
throw createFileSystemProviderError(`File is not a directory`, FileSystemProviderErrorCode.FileNotADirectory);
|
|
112
|
+
}
|
|
113
|
+
const resourcePathParts = resourceURI.path.split('/');
|
|
114
|
+
const output = ( new Map());
|
|
115
|
+
for (const content of contents) {
|
|
116
|
+
const contentURI = ( URI.parse(content.uri));
|
|
117
|
+
const contentPathParts = contentURI.path.split('/');
|
|
118
|
+
if (contentPathParts.length <= resourcePathParts.length || !resourcePathParts.every((part, index) => equalsIgnoreCase(part, contentPathParts[index]))) {
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
else if (contentPathParts.length > resourcePathParts.length + 1) {
|
|
122
|
+
output.set(contentPathParts[resourcePathParts.length], FileType.Directory);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
const name = contentPathParts[contentPathParts.length - 1];
|
|
126
|
+
output.set(name, contentToBuffer(content).byteLength > 0 ? FileType.File : FileType.Directory);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return [...output];
|
|
130
|
+
}
|
|
131
|
+
mkdir(resource) {
|
|
132
|
+
throw createFileSystemProviderError('write is not supported', FileSystemProviderErrorCode.NoPermissions);
|
|
133
|
+
}
|
|
134
|
+
writeFile(resource, content, opts) {
|
|
135
|
+
throw createFileSystemProviderError('write is not supported', FileSystemProviderErrorCode.NoPermissions);
|
|
136
|
+
}
|
|
137
|
+
delete(resource, opts) {
|
|
138
|
+
throw createFileSystemProviderError('delete is not supported', FileSystemProviderErrorCode.NoPermissions);
|
|
139
|
+
}
|
|
140
|
+
rename(from, to, opts) {
|
|
141
|
+
throw createFileSystemProviderError('rename is not supported', FileSystemProviderErrorCode.NoPermissions);
|
|
142
|
+
}
|
|
143
|
+
async _readFile(resource, token) {
|
|
144
|
+
const { forSameURI, contents } = await this._readURI(resource);
|
|
145
|
+
if (!forSameURI.length) {
|
|
146
|
+
if (!contents.length) {
|
|
147
|
+
throw createFileSystemProviderError(`File not found`, FileSystemProviderErrorCode.FileNotFound);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
throw createFileSystemProviderError(`File is a directory`, FileSystemProviderErrorCode.FileIsADirectory);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return contentToBuffer(forSameURI[0]);
|
|
154
|
+
}
|
|
155
|
+
_decodeURI(uri) {
|
|
156
|
+
let definitionId;
|
|
157
|
+
let resourceURI;
|
|
158
|
+
try {
|
|
159
|
+
({ definitionId, resourceURI } = McpResourceURI.toServer(uri));
|
|
160
|
+
}
|
|
161
|
+
catch (e) {
|
|
162
|
+
throw createFileSystemProviderError(String(e), FileSystemProviderErrorCode.FileNotFound);
|
|
163
|
+
}
|
|
164
|
+
if (resourceURI.path.endsWith('/')) {
|
|
165
|
+
resourceURI = resourceURI.with({ path: resourceURI.path.slice(0, -1) });
|
|
166
|
+
}
|
|
167
|
+
const server = this._mcpService.servers.get().find(s => s.definition.id === definitionId);
|
|
168
|
+
if (!server) {
|
|
169
|
+
throw createFileSystemProviderError(`MCP server ${definitionId} not found`, FileSystemProviderErrorCode.FileNotFound);
|
|
170
|
+
}
|
|
171
|
+
const cap = server.capabilities.get();
|
|
172
|
+
if (cap !== undefined && !(cap & McpCapability.Resources)) {
|
|
173
|
+
throw createFileSystemProviderError(`MCP server ${definitionId} does not support resources`, FileSystemProviderErrorCode.FileNotFound);
|
|
174
|
+
}
|
|
175
|
+
return { definitionId, resourceURI, server };
|
|
176
|
+
}
|
|
177
|
+
async _readURI(uri, token) {
|
|
178
|
+
const { resourceURI, server } = this._decodeURI(uri);
|
|
179
|
+
const res = await McpServer.callOn(server, r => r.readResource({ uri: ( resourceURI.toString(true)) }, token), token);
|
|
180
|
+
return {
|
|
181
|
+
contents: res.contents,
|
|
182
|
+
resourceURI,
|
|
183
|
+
forSameURI: res.contents.filter(c => equalsUriPath(c.uri, resourceURI)),
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
McpResourceFilesystem = ( __decorate([
|
|
188
|
+
( __param(0, IInstantiationService)),
|
|
189
|
+
( __param(1, IFileService))
|
|
190
|
+
], McpResourceFilesystem));
|
|
191
|
+
function equalsUriPath(a, b) {
|
|
192
|
+
return equalsIgnoreCase(( URI.parse(a)).path, b.path);
|
|
193
|
+
}
|
|
194
|
+
function contentToBuffer(content) {
|
|
195
|
+
if ('text' in content) {
|
|
196
|
+
return VSBuffer.fromString(content.text).buffer;
|
|
197
|
+
}
|
|
198
|
+
else if ('blob' in content) {
|
|
199
|
+
return decodeBase64(content.blob).buffer;
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
throw createFileSystemProviderError('Unknown content type', FileSystemProviderErrorCode.Unknown);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export { McpResourceFilesystem };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Disposable } from "@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle";
|
|
2
|
+
import { IStorageService } from "@codingame/monaco-vscode-api/vscode/vs/platform/storage/common/storage.service";
|
|
3
|
+
import { IMcpServer } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypes";
|
|
4
|
+
import { MCP } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/modelContextProtocol";
|
|
5
|
+
interface ISamplingStoredData {
|
|
6
|
+
head: number;
|
|
7
|
+
bins: number[];
|
|
8
|
+
lastReqs: {
|
|
9
|
+
request: MCP.SamplingMessage[];
|
|
10
|
+
response: string;
|
|
11
|
+
at: number;
|
|
12
|
+
model: string;
|
|
13
|
+
}[];
|
|
14
|
+
}
|
|
15
|
+
export declare class McpSamplingLog extends Disposable {
|
|
16
|
+
private readonly _storageService;
|
|
17
|
+
private readonly _logs;
|
|
18
|
+
constructor(_storageService: IStorageService);
|
|
19
|
+
has(server: IMcpServer): boolean;
|
|
20
|
+
get(server: IMcpServer): Readonly<ISamplingStoredData | undefined>;
|
|
21
|
+
getAsText(server: IMcpServer): string;
|
|
22
|
+
private _formatRecentRequests;
|
|
23
|
+
add(server: IMcpServer, request: MCP.SamplingMessage[], response: string, model: string): Promise<void>;
|
|
24
|
+
private _getLogStorageForServer;
|
|
25
|
+
}
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
|
|
2
|
+
import { __decorate, __param } from '@codingame/monaco-vscode-api/external/tslib/tslib.es6';
|
|
3
|
+
import { Disposable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
|
|
4
|
+
import { localize } from '@codingame/monaco-vscode-api/vscode/vs/nls';
|
|
5
|
+
import { observableMemento } from '@codingame/monaco-vscode-1cb11a73-359e-5a2f-9e95-6989cc9858ee-common/vscode/vs/platform/observable/common/observableMemento';
|
|
6
|
+
import { StorageScope, StorageTarget } from '@codingame/monaco-vscode-api/vscode/vs/platform/storage/common/storage';
|
|
7
|
+
import { IStorageService } from '@codingame/monaco-vscode-api/vscode/vs/platform/storage/common/storage.service';
|
|
8
|
+
|
|
9
|
+
var Constants;
|
|
10
|
+
(function (Constants) {
|
|
11
|
+
Constants[Constants["SamplingRetentionDays"] = 7] = "SamplingRetentionDays";
|
|
12
|
+
Constants[Constants["MsPerDay"] = 86400000] = "MsPerDay";
|
|
13
|
+
Constants[Constants["SamplingRetentionMs"] = 604800000] = "SamplingRetentionMs";
|
|
14
|
+
Constants[Constants["SamplingLastNMessage"] = 30] = "SamplingLastNMessage";
|
|
15
|
+
})(Constants || (Constants = {}));
|
|
16
|
+
const samplingMemento = observableMemento({
|
|
17
|
+
defaultValue: ( new Map()),
|
|
18
|
+
key: 'mcp.sampling.logs',
|
|
19
|
+
toStorage: v => JSON.stringify(Array.from(v.entries())),
|
|
20
|
+
fromStorage: v => ( new Map(JSON.parse(v))),
|
|
21
|
+
});
|
|
22
|
+
let McpSamplingLog = class McpSamplingLog extends Disposable {
|
|
23
|
+
constructor(_storageService) {
|
|
24
|
+
super();
|
|
25
|
+
this._storageService = _storageService;
|
|
26
|
+
this._logs = {};
|
|
27
|
+
}
|
|
28
|
+
has(server) {
|
|
29
|
+
const storage = this._getLogStorageForServer(server);
|
|
30
|
+
return ( storage.get().has(server.definition.id));
|
|
31
|
+
}
|
|
32
|
+
get(server) {
|
|
33
|
+
const storage = this._getLogStorageForServer(server);
|
|
34
|
+
return storage.get().get(server.definition.id);
|
|
35
|
+
}
|
|
36
|
+
getAsText(server) {
|
|
37
|
+
const storage = this._getLogStorageForServer(server);
|
|
38
|
+
const record = storage.get().get(server.definition.id);
|
|
39
|
+
if (!record) {
|
|
40
|
+
return '';
|
|
41
|
+
}
|
|
42
|
+
const parts = [];
|
|
43
|
+
const total = record.bins.reduce((sum, value) => sum + value, 0);
|
|
44
|
+
parts.push(( localize(7956, '{0} total requests in the last 7 days.', total)));
|
|
45
|
+
parts.push(this._formatRecentRequests(record));
|
|
46
|
+
return parts.join('\n');
|
|
47
|
+
}
|
|
48
|
+
_formatRecentRequests(data) {
|
|
49
|
+
if (!data.lastReqs.length) {
|
|
50
|
+
return '\nNo recent requests.';
|
|
51
|
+
}
|
|
52
|
+
const result = [];
|
|
53
|
+
for (let i = 0; i < data.lastReqs.length; i++) {
|
|
54
|
+
const { request, response, at, model } = data.lastReqs[i];
|
|
55
|
+
result.push(`\n[${i + 1}] ${( new Date(at)).toISOString()} ${model}`);
|
|
56
|
+
result.push(' Request:');
|
|
57
|
+
for (const msg of request) {
|
|
58
|
+
const role = msg.role.padEnd(9);
|
|
59
|
+
let content = '';
|
|
60
|
+
if ('text' in msg.content && msg.content.type === 'text') {
|
|
61
|
+
content = msg.content.text;
|
|
62
|
+
}
|
|
63
|
+
else if ('data' in msg.content) {
|
|
64
|
+
content = `[${msg.content.type} data: ${msg.content.mimeType}]`;
|
|
65
|
+
}
|
|
66
|
+
result.push(` ${role}: ${content}`);
|
|
67
|
+
}
|
|
68
|
+
result.push(' Response:');
|
|
69
|
+
result.push(` ${response}`);
|
|
70
|
+
}
|
|
71
|
+
return result.join('\n');
|
|
72
|
+
}
|
|
73
|
+
async add(server, request, response, model) {
|
|
74
|
+
const now = Date.now();
|
|
75
|
+
const utcOrdinal = Math.floor(now / Constants.MsPerDay);
|
|
76
|
+
const storage = this._getLogStorageForServer(server);
|
|
77
|
+
const next = ( new Map(storage.get()));
|
|
78
|
+
let record = next.get(server.definition.id);
|
|
79
|
+
if (!record) {
|
|
80
|
+
record = {
|
|
81
|
+
head: utcOrdinal,
|
|
82
|
+
bins: Array.from({ length: Constants.SamplingRetentionDays }, () => 0),
|
|
83
|
+
lastReqs: [],
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
for (let i = 0; i < (utcOrdinal - record.head) && i < Constants.SamplingRetentionDays; i++) {
|
|
88
|
+
record.bins.pop();
|
|
89
|
+
record.bins.unshift(0);
|
|
90
|
+
}
|
|
91
|
+
record.head = utcOrdinal;
|
|
92
|
+
}
|
|
93
|
+
record.bins[0]++;
|
|
94
|
+
record.lastReqs.unshift({ request, response, at: now, model });
|
|
95
|
+
while (record.lastReqs.length > Constants.SamplingLastNMessage) {
|
|
96
|
+
record.lastReqs.pop();
|
|
97
|
+
}
|
|
98
|
+
next.set(server.definition.id, record);
|
|
99
|
+
storage.set(next, undefined);
|
|
100
|
+
}
|
|
101
|
+
_getLogStorageForServer(server) {
|
|
102
|
+
const scope = server.readDefinitions().get().collection?.scope ?? StorageScope.WORKSPACE;
|
|
103
|
+
return this._logs[scope] ??= this._register(samplingMemento(scope, StorageTarget.MACHINE, this._storageService));
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
McpSamplingLog = ( __decorate([
|
|
107
|
+
( __param(0, IStorageService))
|
|
108
|
+
], McpSamplingLog));
|
|
109
|
+
|
|
110
|
+
export { McpSamplingLog };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { CancellationToken } from "@codingame/monaco-vscode-api/vscode/vs/base/common/cancellation";
|
|
2
|
+
import { Disposable } from "@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle";
|
|
3
|
+
import { ICommandService } from "@codingame/monaco-vscode-api/vscode/vs/platform/commands/common/commands.service";
|
|
4
|
+
import { IConfigurationService } from "@codingame/monaco-vscode-api/vscode/vs/platform/configuration/common/configuration.service";
|
|
5
|
+
import { IDialogService } from "@codingame/monaco-vscode-api/vscode/vs/platform/dialogs/common/dialogs.service";
|
|
6
|
+
import { IInstantiationService } from "@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation";
|
|
7
|
+
import { INotificationService } from "@codingame/monaco-vscode-api/vscode/vs/platform/notification/common/notification.service";
|
|
8
|
+
import { ILanguageModelsService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/languageModels.service";
|
|
9
|
+
import { IMcpServerSamplingConfiguration } from "@codingame/monaco-vscode-aa9ead53-dfd3-59da-b9e7-f163d201de8d-common/vscode/vs/workbench/contrib/mcp/common/mcpConfiguration";
|
|
10
|
+
import { IMcpServer, ISamplingOptions, ISamplingResult } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypes";
|
|
11
|
+
import { IMcpSamplingService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypes.service";
|
|
12
|
+
export declare class McpSamplingService extends Disposable implements IMcpSamplingService {
|
|
13
|
+
private readonly _languageModelsService;
|
|
14
|
+
private readonly _configurationService;
|
|
15
|
+
private readonly _dialogService;
|
|
16
|
+
private readonly _notificationService;
|
|
17
|
+
private readonly _commandService;
|
|
18
|
+
readonly _serviceBrand: undefined;
|
|
19
|
+
private readonly _sessionSets;
|
|
20
|
+
private readonly _logs;
|
|
21
|
+
constructor(_languageModelsService: ILanguageModelsService, _configurationService: IConfigurationService, _dialogService: IDialogService, _notificationService: INotificationService, _commandService: ICommandService, instaService: IInstantiationService);
|
|
22
|
+
sample(opts: ISamplingOptions, token?: Readonly<CancellationToken>): Promise<ISamplingResult>;
|
|
23
|
+
hasLogs(server: IMcpServer): boolean;
|
|
24
|
+
getLogText(server: IMcpServer): string;
|
|
25
|
+
private _getMatchingModel;
|
|
26
|
+
private allowButtons;
|
|
27
|
+
private _showContextual;
|
|
28
|
+
private _notify;
|
|
29
|
+
private _getMatchingModelInner;
|
|
30
|
+
private _configKey;
|
|
31
|
+
getConfig(server: IMcpServer): IMcpServerSamplingConfiguration;
|
|
32
|
+
private _getConfig;
|
|
33
|
+
updateConfig(server: IMcpServer, mutate: (r: IMcpServerSamplingConfiguration) => unknown): Promise<{
|
|
34
|
+
allowedDuringChat?: boolean;
|
|
35
|
+
allowedOutsideChat?: boolean;
|
|
36
|
+
allowedModels?: string[];
|
|
37
|
+
}>;
|
|
38
|
+
}
|