@theia/ai-ide 1.64.0-next.0 → 1.64.0-next.17
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/lib/browser/ai-configuration/agent-configuration-widget.d.ts.map +1 -1
- package/lib/browser/ai-configuration/agent-configuration-widget.js +1 -1
- package/lib/browser/ai-configuration/agent-configuration-widget.js.map +1 -1
- package/lib/browser/ai-configuration/template-settings-renderer.d.ts +1 -2
- package/lib/browser/ai-configuration/template-settings-renderer.d.ts.map +1 -1
- package/lib/browser/ai-configuration/template-settings-renderer.js +5 -3
- package/lib/browser/ai-configuration/template-settings-renderer.js.map +1 -1
- package/lib/browser/app-tester-chat-agent.d.ts +1 -1
- package/lib/browser/app-tester-chat-agent.d.ts.map +1 -1
- package/lib/browser/app-tester-chat-agent.js +32 -10
- package/lib/browser/app-tester-chat-agent.js.map +1 -1
- package/lib/browser/app-tester-chat-functions.d.ts +25 -0
- package/lib/browser/app-tester-chat-functions.d.ts.map +1 -0
- package/lib/browser/app-tester-chat-functions.js +170 -0
- package/lib/browser/app-tester-chat-functions.js.map +1 -0
- package/lib/browser/frontend-module.d.ts.map +1 -1
- package/lib/browser/frontend-module.js +10 -0
- package/lib/browser/frontend-module.js.map +1 -1
- package/lib/common/app-tester-chat-functions.d.ts +5 -0
- package/lib/common/app-tester-chat-functions.d.ts.map +1 -0
- package/lib/common/app-tester-chat-functions.js +23 -0
- package/lib/common/app-tester-chat-functions.js.map +1 -0
- package/lib/common/browser-automation-protocol.d.ts +15 -0
- package/lib/common/browser-automation-protocol.d.ts.map +1 -0
- package/lib/common/browser-automation-protocol.js +22 -0
- package/lib/common/browser-automation-protocol.js.map +1 -0
- package/lib/node/app-tester-agent/browser-automation-impl.d.ts +18 -0
- package/lib/node/app-tester-agent/browser-automation-impl.d.ts.map +1 -0
- package/lib/node/app-tester-agent/browser-automation-impl.js +96 -0
- package/lib/node/app-tester-agent/browser-automation-impl.js.map +1 -0
- package/lib/node/backend-module.d.ts +4 -0
- package/lib/node/backend-module.d.ts.map +1 -0
- package/lib/node/backend-module.js +35 -0
- package/lib/node/backend-module.js.map +1 -0
- package/package.json +21 -19
- package/src/browser/ai-configuration/agent-configuration-widget.tsx +0 -1
- package/src/browser/ai-configuration/template-settings-renderer.tsx +5 -5
- package/src/browser/app-tester-chat-agent.ts +135 -111
- package/src/browser/app-tester-chat-functions.ts +170 -0
- package/src/browser/frontend-module.ts +19 -1
- package/src/common/app-tester-chat-functions.ts +20 -0
- package/src/common/browser-automation-protocol.ts +32 -0
- package/src/node/app-tester-agent/browser-automation-impl.ts +107 -0
- package/src/node/backend-module.ts +38 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2025 EclipseSource GmbH.
|
|
4
|
+
//
|
|
5
|
+
// This program and the accompanying materials are made available under the
|
|
6
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
7
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
8
|
+
//
|
|
9
|
+
// This Source Code may also be made available under the following Secondary
|
|
10
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
11
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
12
|
+
// with the GNU Classpath Exception which is available at
|
|
13
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
14
|
+
//
|
|
15
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
|
+
// *****************************************************************************
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.BrowserAutomationClient = exports.BrowserAutomation = exports.browserAutomationPath = void 0;
|
|
19
|
+
exports.browserAutomationPath = '/services/automation/browser';
|
|
20
|
+
exports.BrowserAutomation = Symbol('BrowserAutomation');
|
|
21
|
+
exports.BrowserAutomationClient = Symbol('BrowserAutomationClient');
|
|
22
|
+
//# sourceMappingURL=browser-automation-protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-automation-protocol.js","sourceRoot":"","sources":["../../src/common/browser-automation-protocol.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,yCAAyC;AACzC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;;AAEnE,QAAA,qBAAqB,GAAG,8BAA8B,CAAC;AACvD,QAAA,iBAAiB,GAAG,MAAM,CAAC,mBAAmB,CAAC,CAAC;AAYhD,QAAA,uBAAuB,GAAG,MAAM,CAAC,yBAAyB,CAAC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type RpcServer } from '@theia/core';
|
|
2
|
+
import { Browser, Page } from 'puppeteer-core';
|
|
3
|
+
import type { BrowserAutomation, BrowserAutomationClient, LaunchResult } from '../../common/browser-automation-protocol';
|
|
4
|
+
export declare class BrowserAutomationImpl implements RpcServer<BrowserAutomationClient>, BrowserAutomation {
|
|
5
|
+
protected _browser?: Browser;
|
|
6
|
+
protected _page?: Page;
|
|
7
|
+
protected client?: BrowserAutomationClient;
|
|
8
|
+
protected get browser(): Browser;
|
|
9
|
+
protected get page(): Page;
|
|
10
|
+
isRunning(): Promise<boolean>;
|
|
11
|
+
launch(remoteDebuggingPort: number): Promise<LaunchResult | undefined>;
|
|
12
|
+
close(): Promise<void>;
|
|
13
|
+
queryDom(selector?: string): Promise<string>;
|
|
14
|
+
dispose(): void;
|
|
15
|
+
setClient(client: BrowserAutomationClient | undefined): void;
|
|
16
|
+
getClient?(): BrowserAutomationClient | undefined;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=browser-automation-impl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-automation-impl.d.ts","sourceRoot":"","sources":["../../../src/node/app-tester-agent/browser-automation-impl.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAE,OAAO,EAAU,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AAIzH,qBACa,qBAAsB,YAAW,SAAS,CAAC,uBAAuB,CAAC,EAAE,iBAAiB;IAC/F,SAAS,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC7B,SAAS,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC;IACvB,SAAS,CAAC,MAAM,CAAC,EAAE,uBAAuB,CAAC;IAE3C,SAAS,KAAK,OAAO,IAAI,OAAO,CAK/B;IAED,SAAS,KAAK,IAAI,IAAI,IAAI,CAKzB;IAEK,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAI7B,MAAM,CAAC,mBAAmB,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IAoBtE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAqBlD,OAAO,IAAI,IAAI;IAKf,SAAS,CAAC,MAAM,EAAE,uBAAuB,GAAG,SAAS,GAAG,IAAI;IAI5D,SAAS,CAAC,IAAI,uBAAuB,GAAG,SAAS;CAIpD"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2025 EclipseSource GmbH.
|
|
4
|
+
//
|
|
5
|
+
// This program and the accompanying materials are made available under the
|
|
6
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
7
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
8
|
+
//
|
|
9
|
+
// This Source Code may also be made available under the following Secondary
|
|
10
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
11
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
12
|
+
// with the GNU Classpath Exception which is available at
|
|
13
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
14
|
+
//
|
|
15
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
|
+
// *****************************************************************************
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.BrowserAutomationImpl = void 0;
|
|
19
|
+
const tslib_1 = require("tslib");
|
|
20
|
+
const inversify_1 = require("@theia/core/shared/inversify");
|
|
21
|
+
const puppeteer_core_1 = require("puppeteer-core");
|
|
22
|
+
const MAX_DOM_LENGTH = 50000;
|
|
23
|
+
let BrowserAutomationImpl = class BrowserAutomationImpl {
|
|
24
|
+
get browser() {
|
|
25
|
+
if (!this._browser) {
|
|
26
|
+
throw new Error('Browser is not launched');
|
|
27
|
+
}
|
|
28
|
+
return this._browser;
|
|
29
|
+
}
|
|
30
|
+
get page() {
|
|
31
|
+
if (!this._page) {
|
|
32
|
+
throw new Error('Page is not created');
|
|
33
|
+
}
|
|
34
|
+
return this._page;
|
|
35
|
+
}
|
|
36
|
+
async isRunning() {
|
|
37
|
+
return this._browser !== undefined && this._browser.connected;
|
|
38
|
+
}
|
|
39
|
+
async launch(remoteDebuggingPort) {
|
|
40
|
+
if (this._browser) {
|
|
41
|
+
await this.close();
|
|
42
|
+
}
|
|
43
|
+
const browser = await (0, puppeteer_core_1.launch)({
|
|
44
|
+
headless: false,
|
|
45
|
+
channel: 'chrome',
|
|
46
|
+
args: [
|
|
47
|
+
`--remote-debugging-port=${remoteDebuggingPort}`
|
|
48
|
+
],
|
|
49
|
+
});
|
|
50
|
+
this._browser = browser;
|
|
51
|
+
// The initial page will be used per default
|
|
52
|
+
this._page = (await browser.pages())[0];
|
|
53
|
+
return {
|
|
54
|
+
remoteDebuggingPort
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
async close() {
|
|
58
|
+
var _a;
|
|
59
|
+
await ((_a = this._browser) === null || _a === void 0 ? void 0 : _a.close());
|
|
60
|
+
this._browser = undefined;
|
|
61
|
+
}
|
|
62
|
+
async queryDom(selector) {
|
|
63
|
+
const page = this.page;
|
|
64
|
+
let content = '';
|
|
65
|
+
if (selector) {
|
|
66
|
+
const element = await page.$(selector);
|
|
67
|
+
if (!element) {
|
|
68
|
+
throw new Error(`Element with selector "${selector}" not found`);
|
|
69
|
+
}
|
|
70
|
+
content = await page.evaluate(el => el.outerHTML, element);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
content = await page.content();
|
|
74
|
+
}
|
|
75
|
+
if (content.length > MAX_DOM_LENGTH) {
|
|
76
|
+
return 'The queried DOM is too large. Please provide a more specific query.';
|
|
77
|
+
}
|
|
78
|
+
return content;
|
|
79
|
+
}
|
|
80
|
+
dispose() {
|
|
81
|
+
var _a;
|
|
82
|
+
(_a = this._browser) === null || _a === void 0 ? void 0 : _a.close();
|
|
83
|
+
this._browser = undefined;
|
|
84
|
+
}
|
|
85
|
+
setClient(client) {
|
|
86
|
+
this.client = client;
|
|
87
|
+
}
|
|
88
|
+
getClient() {
|
|
89
|
+
return this.client;
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
exports.BrowserAutomationImpl = BrowserAutomationImpl;
|
|
93
|
+
exports.BrowserAutomationImpl = BrowserAutomationImpl = tslib_1.__decorate([
|
|
94
|
+
(0, inversify_1.injectable)()
|
|
95
|
+
], BrowserAutomationImpl);
|
|
96
|
+
//# sourceMappingURL=browser-automation-impl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-automation-impl.js","sourceRoot":"","sources":["../../../src/node/app-tester-agent/browser-automation-impl.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backend-module.d.ts","sourceRoot":"","sources":["../../src/node/backend-module.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;;AAiB/D,wBAGG"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2025 EclipseSource GmbH.
|
|
4
|
+
//
|
|
5
|
+
// This program and the accompanying materials are made available under the
|
|
6
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
7
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
8
|
+
//
|
|
9
|
+
// This Source Code may also be made available under the following Secondary
|
|
10
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
11
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
12
|
+
// with the GNU Classpath Exception which is available at
|
|
13
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
14
|
+
//
|
|
15
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
|
+
// *****************************************************************************
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
const core_1 = require("@theia/core");
|
|
19
|
+
const inversify_1 = require("@theia/core/shared/inversify");
|
|
20
|
+
const browser_automation_protocol_1 = require("../common/browser-automation-protocol");
|
|
21
|
+
const browser_automation_impl_1 = require("./app-tester-agent/browser-automation-impl");
|
|
22
|
+
const connection_container_module_1 = require("@theia/core/lib/node/messaging/connection-container-module");
|
|
23
|
+
const browserAutomationModule = connection_container_module_1.ConnectionContainerModule.create(({ bind, bindBackendService, bindFrontendService }) => {
|
|
24
|
+
bind(browser_automation_protocol_1.BrowserAutomation).to(browser_automation_impl_1.BrowserAutomationImpl).inSingletonScope();
|
|
25
|
+
bind(core_1.ConnectionHandler).toDynamicValue(ctx => new core_1.RpcConnectionHandler(browser_automation_protocol_1.browserAutomationPath, client => {
|
|
26
|
+
const server = ctx.container.get(browser_automation_protocol_1.BrowserAutomation);
|
|
27
|
+
server.setClient(client);
|
|
28
|
+
client.onDidCloseConnection(() => server.close());
|
|
29
|
+
return server;
|
|
30
|
+
})).inSingletonScope();
|
|
31
|
+
});
|
|
32
|
+
exports.default = new inversify_1.ContainerModule(bind => {
|
|
33
|
+
bind(connection_container_module_1.ConnectionContainerModule).toConstantValue(browserAutomationModule);
|
|
34
|
+
});
|
|
35
|
+
//# sourceMappingURL=backend-module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backend-module.js","sourceRoot":"","sources":["../../src/node/backend-module.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,yCAAyC;AACzC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;AAEhF,sCAAsE;AACtE,4DAA+D;AAC/D,uFAA+H;AAC/H,wFAAmF;AACnF,4GAAuG;AAEvG,MAAM,uBAAuB,GAAG,uDAAyB,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,EAAE,EAAE;IACnH,IAAI,CAAC,+CAAiB,CAAC,CAAC,EAAE,CAAC,+CAAqB,CAAC,CAAC,gBAAgB,EAAE,CAAC;IACrE,IAAI,CAAC,wBAAiB,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CACzC,IAAI,2BAAoB,CAA0B,mDAAqB,EAAE,MAAM,CAAC,EAAE;QAC9E,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAwB,+CAAiB,CAAC,CAAC;QAC3E,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACzB,MAAM,CAAC,oBAAoB,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;QAClD,OAAO,MAAM,CAAC;IAClB,CAAC,CAAC,CACL,CAAC,gBAAgB,EAAE,CAAC;AACzB,CAAC,CAAC,CAAC;AAEH,kBAAe,IAAI,2BAAe,CAAC,IAAI,CAAC,EAAE;IACtC,IAAI,CAAC,uDAAyB,CAAC,CAAC,eAAe,CAAC,uBAAuB,CAAC,CAAC;AAE7E,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theia/ai-ide",
|
|
3
|
-
"version": "1.64.0-next.
|
|
3
|
+
"version": "1.64.0-next.17+58507bbed",
|
|
4
4
|
"description": "AI IDE Agents Extension",
|
|
5
5
|
"license": "EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -15,35 +15,37 @@
|
|
|
15
15
|
"theia-extension"
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@theia/ai-chat": "1.64.0-next.
|
|
19
|
-
"@theia/ai-chat-ui": "1.64.0-next.
|
|
20
|
-
"@theia/ai-core": "1.64.0-next.
|
|
21
|
-
"@theia/ai-mcp": "1.64.0-next.
|
|
22
|
-
"@theia/core": "1.64.0-next.
|
|
23
|
-
"@theia/filesystem": "1.64.0-next.
|
|
24
|
-
"@theia/markers": "1.64.0-next.
|
|
25
|
-
"@theia/monaco": "1.64.0-next.
|
|
26
|
-
"@theia/navigator": "1.64.0-next.
|
|
27
|
-
"@theia/search-in-workspace": "1.64.0-next.
|
|
28
|
-
"@theia/task": "1.64.0-next.
|
|
29
|
-
"@theia/terminal": "1.64.0-next.
|
|
30
|
-
"@theia/workspace": "1.64.0-next.
|
|
18
|
+
"@theia/ai-chat": "1.64.0-next.17+58507bbed",
|
|
19
|
+
"@theia/ai-chat-ui": "1.64.0-next.17+58507bbed",
|
|
20
|
+
"@theia/ai-core": "1.64.0-next.17+58507bbed",
|
|
21
|
+
"@theia/ai-mcp": "1.64.0-next.17+58507bbed",
|
|
22
|
+
"@theia/core": "1.64.0-next.17+58507bbed",
|
|
23
|
+
"@theia/filesystem": "1.64.0-next.17+58507bbed",
|
|
24
|
+
"@theia/markers": "1.64.0-next.17+58507bbed",
|
|
25
|
+
"@theia/monaco": "1.64.0-next.17+58507bbed",
|
|
26
|
+
"@theia/navigator": "1.64.0-next.17+58507bbed",
|
|
27
|
+
"@theia/search-in-workspace": "1.64.0-next.17+58507bbed",
|
|
28
|
+
"@theia/task": "1.64.0-next.17+58507bbed",
|
|
29
|
+
"@theia/terminal": "1.64.0-next.17+58507bbed",
|
|
30
|
+
"@theia/workspace": "1.64.0-next.17+58507bbed",
|
|
31
31
|
"date-fns": "^4.1.0",
|
|
32
32
|
"ignore": "^6.0.0",
|
|
33
33
|
"js-yaml": "^4.1.0",
|
|
34
|
-
"minimatch": "^9.0.0"
|
|
34
|
+
"minimatch": "^9.0.0",
|
|
35
|
+
"puppeteer-core": "^24.10.0"
|
|
35
36
|
},
|
|
36
37
|
"publishConfig": {
|
|
37
38
|
"access": "public"
|
|
38
39
|
},
|
|
39
40
|
"devDependencies": {
|
|
40
|
-
"@theia/cli": "1.64.0-next.
|
|
41
|
-
"@theia/test": "1.64.0-next.
|
|
41
|
+
"@theia/cli": "1.64.0-next.17+58507bbed",
|
|
42
|
+
"@theia/test": "1.64.0-next.17+58507bbed"
|
|
42
43
|
},
|
|
43
44
|
"theiaExtensions": [
|
|
44
45
|
{
|
|
45
46
|
"frontend": "lib/browser/frontend-module",
|
|
46
|
-
"secondaryWindow": "lib/browser/frontend-module"
|
|
47
|
+
"secondaryWindow": "lib/browser/frontend-module",
|
|
48
|
+
"backend": "lib/node/backend-module"
|
|
47
49
|
}
|
|
48
50
|
],
|
|
49
51
|
"files": [
|
|
@@ -61,5 +63,5 @@
|
|
|
61
63
|
"nyc": {
|
|
62
64
|
"extends": "../../configs/nyc.json"
|
|
63
65
|
},
|
|
64
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "58507bbedb95724735981f44f034e7036fa2f19e"
|
|
65
67
|
}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
//
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
|
-
import {
|
|
16
|
+
import { PromptService, PromptVariantSet } from '@theia/ai-core/lib/common';
|
|
17
17
|
import * as React from '@theia/core/shared/react';
|
|
18
18
|
import { nls } from '@theia/core/lib/common/nls';
|
|
19
19
|
|
|
@@ -21,14 +21,12 @@ export interface PromptVariantRendererProps {
|
|
|
21
21
|
agentId: string;
|
|
22
22
|
promptVariantSet: PromptVariantSet;
|
|
23
23
|
promptService: PromptService;
|
|
24
|
-
aiSettingsService: AISettingsService;
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
export const PromptVariantRenderer: React.FC<PromptVariantRendererProps> = ({
|
|
28
27
|
agentId,
|
|
29
28
|
promptVariantSet,
|
|
30
29
|
promptService,
|
|
31
|
-
aiSettingsService,
|
|
32
30
|
}) => {
|
|
33
31
|
const variantIds = promptService.getVariantIds(promptVariantSet.id);
|
|
34
32
|
const defaultVariantId = promptService.getDefaultVariantId(promptVariantSet.id);
|
|
@@ -38,9 +36,11 @@ export const PromptVariantRenderer: React.FC<PromptVariantRendererProps> = ({
|
|
|
38
36
|
(async () => {
|
|
39
37
|
const currentVariant =
|
|
40
38
|
await promptService.getSelectedVariantId(promptVariantSet.id);
|
|
41
|
-
|
|
39
|
+
if (currentVariant) {
|
|
40
|
+
setSelectedVariant(currentVariant);
|
|
41
|
+
}
|
|
42
42
|
})();
|
|
43
|
-
}, [promptVariantSet.id,
|
|
43
|
+
}, [promptVariantSet.id, agentId]);
|
|
44
44
|
|
|
45
45
|
const isInvalidVariant = !variantIds.includes(selectedVariant);
|
|
46
46
|
|
|
@@ -25,28 +25,33 @@ import { nls } from '@theia/core';
|
|
|
25
25
|
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
26
26
|
import { MCP_SERVERS_PREF } from '@theia/ai-mcp/lib/browser/mcp-preferences';
|
|
27
27
|
import { PreferenceScope, PreferenceService } from '@theia/core/lib/browser';
|
|
28
|
+
import { QUERY_DOM_FUNCTION_ID, LAUNCH_BROWSER_FUNCTION_ID, CLOSE_BROWSER_FUNCTION_ID, IS_BROWSER_RUNNING_FUNCTION_ID } from '../common/app-tester-chat-functions';
|
|
28
29
|
|
|
29
30
|
export const REQUIRED_MCP_SERVERS: MCPServerDescription[] = [
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
31
|
+
{
|
|
32
|
+
name: 'playwright',
|
|
33
|
+
command: 'npx',
|
|
34
|
+
args: ['-y', '@playwright/mcp@latest',
|
|
35
|
+
'--cdp-endpoint',
|
|
36
|
+
'http://localhost:9222/'],
|
|
37
|
+
autostart: false,
|
|
38
|
+
env: {},
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: 'playwright-visual',
|
|
42
|
+
command: 'npx',
|
|
43
|
+
args: ['-y', '@playwright/mcp@latest', '--vision',
|
|
44
|
+
'--cdp-endpoint',
|
|
45
|
+
'http://localhost:9222/'],
|
|
46
|
+
autostart: false,
|
|
47
|
+
env: {},
|
|
48
|
+
}
|
|
44
49
|
];
|
|
45
50
|
|
|
46
51
|
// Prompt templates
|
|
47
52
|
export const appTesterTemplate: BasePromptFragment = {
|
|
48
|
-
|
|
49
|
-
|
|
53
|
+
id: 'app-tester-system-default',
|
|
54
|
+
template: `{{!-- This prompt is licensed under the MIT License (https://opensource.org/license/mit).
|
|
50
55
|
Made improvements or adaptations to this prompt template? We'd love for you to share it with the community! Contribute back here:
|
|
51
56
|
https://github.com/eclipse-theia/theia/discussions/new?category=prompt-template-contribution --}}
|
|
52
57
|
|
|
@@ -63,6 +68,14 @@ Your role is to inspect the application for user-specified test scenarios throug
|
|
|
63
68
|
You have access to these powerful automation tools:
|
|
64
69
|
${REQUIRED_MCP_SERVERS.map(server => `{{prompt:mcp_${server.name}_tools}}`)}
|
|
65
70
|
|
|
71
|
+
- **~{${LAUNCH_BROWSER_FUNCTION_ID}}**: Launch the browser. This is required before performing any browser interactions. Always launch a new browser when starting a test session.
|
|
72
|
+
- **~{${IS_BROWSER_RUNNING_FUNCTION_ID}}**: Check if the browser is running. If a tool fails by saying that the connection failed, you can verify the connection by using this tool.
|
|
73
|
+
- **~{${CLOSE_BROWSER_FUNCTION_ID}}**: Close the browser.
|
|
74
|
+
- **~{${QUERY_DOM_FUNCTION_ID}}**: Query the DOM for specific elements and their properties. Only use when explicitly requested by the user.
|
|
75
|
+
- **browser_snapshot**: Capture the current state of the page for verification or debugging purposes.
|
|
76
|
+
|
|
77
|
+
Prefer snapshots for investigating the page.
|
|
78
|
+
|
|
66
79
|
## Workflow Approach
|
|
67
80
|
1. **Understand Requirements**: Ask the user to clearly define what needs to be tested
|
|
68
81
|
2. **Launch Browser**: Start a fresh browser instance for testing
|
|
@@ -77,112 +90,123 @@ Some files and other pieces of data may have been added by the user to the conte
|
|
|
77
90
|
};
|
|
78
91
|
|
|
79
92
|
export const appTesterTemplateVariant: BasePromptFragment = {
|
|
80
|
-
|
|
81
|
-
|
|
93
|
+
id: 'app-tester-system-empty',
|
|
94
|
+
template: '',
|
|
82
95
|
};
|
|
83
96
|
|
|
84
97
|
export const AppTesterChatAgentId = 'AppTester';
|
|
85
98
|
@injectable()
|
|
86
99
|
export class AppTesterChatAgent extends AbstractStreamParsingChatAgent {
|
|
87
100
|
|
|
88
|
-
|
|
89
|
-
|
|
101
|
+
@inject(MCPFrontendService)
|
|
102
|
+
protected readonly mcpService: MCPFrontendService;
|
|
90
103
|
|
|
91
|
-
|
|
92
|
-
|
|
104
|
+
@inject(PreferenceService)
|
|
105
|
+
protected readonly preferenceService: PreferenceService;
|
|
93
106
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
107
|
+
id: string = AppTesterChatAgentId;
|
|
108
|
+
name = AppTesterChatAgentId;
|
|
109
|
+
languageModelRequirements: LanguageModelRequirement[] = [{
|
|
110
|
+
purpose: 'chat',
|
|
111
|
+
identifier: 'openai/gpt-4o',
|
|
112
|
+
}];
|
|
113
|
+
protected defaultLanguageModelPurpose: string = 'chat';
|
|
114
|
+
override description = nls.localize('theia/ai/chat/app-tester/description', 'This agent tests your application user interface to verify user-specified test scenarios through the Playwright MCP server. '
|
|
115
|
+
+ 'It can automate testing workflows and provide detailed feedback on application functionality.');
|
|
103
116
|
|
|
104
|
-
|
|
117
|
+
override iconClass: string = 'codicon codicon-beaker';
|
|
105
118
|
protected override systemPromptId: string = 'app-tester-system';
|
|
106
119
|
override prompts = [{ id: 'app-tester-system', defaultVariant: appTesterTemplate, variants: [appTesterTemplateVariant] }];
|
|
107
120
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
121
|
+
/**
|
|
122
|
+
* Override invoke to check if the Playwright MCP server is running, and if not, ask the user if it should be started.
|
|
123
|
+
*/
|
|
124
|
+
override async invoke(request: MutableChatRequestModel): Promise<void> {
|
|
125
|
+
try {
|
|
126
|
+
if (await this.requiresStartingServers()) {
|
|
127
|
+
// Ask the user if they want to start the server
|
|
128
|
+
request.response.response.addContent(new QuestionResponseContentImpl(
|
|
129
|
+
'The Playwright MCP servers are not running. Would you like to start them now? This may install the Playwright MCP servers.',
|
|
130
|
+
[
|
|
131
|
+
{ text: 'Yes, start the servers', value: 'yes' },
|
|
132
|
+
{ text: 'No, cancel', value: 'no' }
|
|
133
|
+
],
|
|
134
|
+
request,
|
|
135
|
+
async selectedOption => {
|
|
136
|
+
if (selectedOption.value === 'yes') {
|
|
137
|
+
// Show progress
|
|
138
|
+
const progress = request.response.addProgressMessage({ content: 'Starting Playwright MCP servers.', show: 'whileIncomplete' });
|
|
139
|
+
try {
|
|
140
|
+
await this.startServers();
|
|
141
|
+
// Remove progress, continue with normal flow
|
|
142
|
+
request.response.updateProgressMessage({ ...progress, show: 'whileIncomplete', status: 'completed' });
|
|
143
|
+
await super.invoke(request);
|
|
144
|
+
} catch (error) {
|
|
145
|
+
request.response.response.addContent(new ErrorChatResponseContentImpl(
|
|
146
|
+
new Error('Failed to start Playwright MCP server: ' + (error instanceof Error ? error.message : String(error)))
|
|
147
|
+
));
|
|
148
|
+
request.response.complete();
|
|
149
|
+
}
|
|
150
|
+
} else {
|
|
151
|
+
// Continue without starting the server
|
|
152
|
+
request.response.response.addContent(new MarkdownChatResponseContentImpl('Please setup the MCP servers.'));
|
|
153
|
+
request.response.complete();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
));
|
|
157
|
+
request.response.waitForInput();
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
// If already running, continue as normal
|
|
161
|
+
await super.invoke(request);
|
|
162
|
+
} catch (error) {
|
|
163
|
+
request.response.response.addContent(new ErrorChatResponseContentImpl(
|
|
164
|
+
new Error('Error checking Playwright MCP server status: ' + (error instanceof Error ? error.message : String(error)))
|
|
143
165
|
));
|
|
144
|
-
request.response.
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
166
|
+
request.response.complete();
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
protected async requiresStartingServers(): Promise<boolean> {
|
|
171
|
+
const allStarted = await Promise.all(REQUIRED_MCP_SERVERS.map(server => this.mcpService.isServerStarted(server.name)));
|
|
172
|
+
return allStarted.some(started => !started);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
protected async startServers(): Promise<void> {
|
|
176
|
+
await this.ensureServersStarted(...REQUIRED_MCP_SERVERS);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Starts the Playwright MCP server if it doesn't exist or isn't running.
|
|
181
|
+
*
|
|
182
|
+
* @returns A promise that resolves when the server is started
|
|
183
|
+
*/
|
|
184
|
+
async ensureServersStarted(...servers: MCPServerDescription[]): Promise<void> {
|
|
185
|
+
try {
|
|
186
|
+
const serversToInstall: MCPServerDescription[] = [];
|
|
187
|
+
const serversToStart: MCPServerDescription[] = [];
|
|
188
|
+
|
|
189
|
+
for (const server of servers) {
|
|
190
|
+
if (!(await this.mcpService.hasServer(server.name))) {
|
|
191
|
+
serversToInstall.push(server);
|
|
192
|
+
}
|
|
193
|
+
if (!(await this.mcpService.isServerStarted(server.name))) {
|
|
194
|
+
serversToStart.push(server);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
for (const server of serversToInstall) {
|
|
199
|
+
const currentServers = this.preferenceService.get<Record<string, MCPServerDescription>>(MCP_SERVERS_PREF, {});
|
|
200
|
+
await this.preferenceService.set(MCP_SERVERS_PREF, { ...currentServers, [server.name]: server }, PreferenceScope.User);
|
|
201
|
+
await this.mcpService.addOrUpdateServer(server);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
for (const server of serversToStart) {
|
|
205
|
+
await this.mcpService.startServer(server.name);
|
|
206
|
+
}
|
|
207
|
+
} catch (error) {
|
|
208
|
+
this.logger.error(`Error starting MCP servers ${servers.map(s => s.name)}: ${error}`);
|
|
209
|
+
throw error;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
188
212
|
}
|