Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/browserView/electron-browser/tools/navigateBrowserTool.ts
13405 views
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 type { CancellationToken } from '../../../../../base/common/cancellation.js';
7
import { Codicon } from '../../../../../base/common/codicons.js';
8
import { MarkdownString } from '../../../../../base/common/htmlContent.js';
9
import { URI } from '../../../../../base/common/uri.js';
10
import { localize } from '../../../../../nls.js';
11
import { IPlaywrightService } from '../../../../../platform/browserView/common/playwrightService.js';
12
import { ToolDataSource, type CountTokensCallback, type IPreparedToolInvocation, type IToolData, type IToolImpl, type IToolInvocation, type IToolInvocationPreparationContext, type IToolResult, type ToolProgress } from '../../../chat/common/tools/languageModelToolsService.js';
13
import { IAgentNetworkFilterService } from '../../../../../platform/networkFilter/common/networkFilterService.js';
14
import { createBrowserPageLink, errorResult, playwrightInvoke } from './browserToolHelpers.js';
15
import { BrowserChatToolReferenceName } from '../../common/browserChatToolReferenceNames.js';
16
import { OpenPageToolId } from './openBrowserTool.js';
17
18
export const NavigateBrowserToolData: IToolData = {
19
id: 'navigate_page',
20
toolReferenceName: BrowserChatToolReferenceName.NavigatePage,
21
displayName: localize('navigateBrowserTool.displayName', 'Navigate Page'),
22
userDescription: localize('navigateBrowserTool.userDescription', 'Navigate or reload a browser page'),
23
modelDescription: 'Navigate a browser page by URL, history, or reload.',
24
icon: Codicon.arrowRight,
25
source: ToolDataSource.Internal,
26
inputSchema: {
27
type: 'object',
28
properties: {
29
pageId: {
30
type: 'string',
31
description: `The browser page ID to navigate, acquired from context or the open tool.`
32
},
33
type: {
34
type: 'string',
35
enum: ['url', 'back', 'forward', 'reload'],
36
description: 'Navigation type: "url" to navigate to a URL (default, requires "url" param), "back" or "forward" for history, "reload" to refresh.'
37
},
38
url: {
39
type: 'string',
40
description: 'The URL to navigate to. Required when type is "url".'
41
},
42
},
43
required: ['pageId'],
44
},
45
};
46
47
interface INavigateBrowserToolParams {
48
pageId: string;
49
type?: 'url' | 'back' | 'forward' | 'reload';
50
url?: string;
51
}
52
53
export class NavigateBrowserTool implements IToolImpl {
54
constructor(
55
@IPlaywrightService private readonly playwrightService: IPlaywrightService,
56
@IAgentNetworkFilterService private readonly agentNetworkFilterService: IAgentNetworkFilterService,
57
) { }
58
59
async prepareToolInvocation(context: IToolInvocationPreparationContext, _token: CancellationToken): Promise<IPreparedToolInvocation | undefined> {
60
const params = context.parameters as INavigateBrowserToolParams;
61
const link = createBrowserPageLink(params.pageId);
62
switch (params.type) {
63
case 'reload':
64
return {
65
invocationMessage: new MarkdownString(localize('browser.reload.invocation', "Reloading {0}", link)),
66
pastTenseMessage: new MarkdownString(localize('browser.reload.past', "Reloaded {0}", link)),
67
icon: Codicon.refresh,
68
};
69
case 'back':
70
return {
71
invocationMessage: new MarkdownString(localize('browser.goBack.invocation', "Navigating backward in {0}", link)),
72
pastTenseMessage: new MarkdownString(localize('browser.goBack.past', "Navigated backward in {0}", link)),
73
icon: Codicon.arrowLeft,
74
};
75
case 'forward':
76
return {
77
invocationMessage: new MarkdownString(localize('browser.goForward.invocation', "Navigating forward in {0}", link)),
78
pastTenseMessage: new MarkdownString(localize('browser.goForward.past', "Navigated forward in {0}", link)),
79
icon: Codicon.arrowRight,
80
};
81
default: {
82
if (!params.url) {
83
throw new Error('The "url" parameter is required when type is "url".');
84
}
85
const parsed = URL.parse(params.url);
86
if (!parsed) {
87
throw new Error('You must provide a complete, valid URL.');
88
}
89
90
const uri = URI.parse(params.url);
91
if (!this.agentNetworkFilterService.isUriAllowed(uri)) {
92
throw new Error(this.agentNetworkFilterService.formatError(uri));
93
}
94
95
return {
96
invocationMessage: new MarkdownString(localize('browser.navigate.invocation', "Navigating to {0} in {1}", parsed.href, link)),
97
pastTenseMessage: new MarkdownString(localize('browser.navigate.past', "Navigated to {0} in {1}", parsed.href, link)),
98
confirmationMessages: {
99
title: localize('browser.navigate.confirmTitle', 'Navigate Browser?'),
100
message: localize('browser.navigate.confirmMessage', 'This will navigate the browser to {0} and allow the agent to access its contents.', parsed.href),
101
allowAutoConfirm: true,
102
},
103
};
104
}
105
}
106
}
107
108
async invoke(invocation: IToolInvocation, _countTokens: CountTokensCallback, _progress: ToolProgress, _token: CancellationToken): Promise<IToolResult> {
109
const params = invocation.parameters as INavigateBrowserToolParams;
110
111
if (!params.pageId) {
112
return errorResult(`No page ID provided. Use '${OpenPageToolId}' first.`);
113
}
114
115
switch (params.type) {
116
case 'reload':
117
return playwrightInvoke(this.playwrightService, params.pageId, (page) => page.reload({ waitUntil: 'domcontentloaded' }));
118
case 'back':
119
return playwrightInvoke(this.playwrightService, params.pageId, (page) => page.goBack({ waitUntil: 'domcontentloaded' }));
120
case 'forward':
121
return playwrightInvoke(this.playwrightService, params.pageId, (page) => page.goForward({ waitUntil: 'domcontentloaded' }));
122
default: {
123
return playwrightInvoke(this.playwrightService, params.pageId, (page, url) => {
124
return page.goto(url, { waitUntil: 'domcontentloaded' });
125
}, params.url!);
126
}
127
}
128
}
129
}
130
131