@equinor/fusion-framework-cli-plugin-copilot 1.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/CHANGELOG.md +24 -0
- package/LICENSE +21 -0
- package/README.md +228 -0
- package/dist/esm/commands/app/command.js +176 -0
- package/dist/esm/commands/app/command.js.map +1 -0
- package/dist/esm/commands/app/eval.js +92 -0
- package/dist/esm/commands/app/eval.js.map +1 -0
- package/dist/esm/commands/app/format.js +93 -0
- package/dist/esm/commands/app/format.js.map +1 -0
- package/dist/esm/commands/app/login.js +71 -0
- package/dist/esm/commands/app/login.js.map +1 -0
- package/dist/esm/commands/app/prompts/execute-step.prompt.js +44 -0
- package/dist/esm/commands/app/prompts/execute-step.prompt.js.map +1 -0
- package/dist/esm/commands/app/prompts/judge.prompt.js +116 -0
- package/dist/esm/commands/app/prompts/judge.prompt.js.map +1 -0
- package/dist/esm/commands/app/prompts/plan.prompt.js +47 -0
- package/dist/esm/commands/app/prompts/plan.prompt.js.map +1 -0
- package/dist/esm/commands/app/prompts/step.prompt.js +42 -0
- package/dist/esm/commands/app/prompts/step.prompt.js.map +1 -0
- package/dist/esm/commands/app/prompts/system.dev-server.prompt.js +21 -0
- package/dist/esm/commands/app/prompts/system.dev-server.prompt.js.map +1 -0
- package/dist/esm/commands/app/prompts/system.prompt.js +77 -0
- package/dist/esm/commands/app/prompts/system.prompt.js.map +1 -0
- package/dist/esm/commands/app/server.js +83 -0
- package/dist/esm/commands/app/server.js.map +1 -0
- package/dist/esm/commands/app/session-logger.js +171 -0
- package/dist/esm/commands/app/session-logger.js.map +1 -0
- package/dist/esm/commands/app/tools/click.js +27 -0
- package/dist/esm/commands/app/tools/click.js.map +1 -0
- package/dist/esm/commands/app/tools/errors.js +24 -0
- package/dist/esm/commands/app/tools/errors.js.map +1 -0
- package/dist/esm/commands/app/tools/eval-js.js +36 -0
- package/dist/esm/commands/app/tools/eval-js.js.map +1 -0
- package/dist/esm/commands/app/tools/fill.js +28 -0
- package/dist/esm/commands/app/tools/fill.js.map +1 -0
- package/dist/esm/commands/app/tools/find.js +44 -0
- package/dist/esm/commands/app/tools/find.js.map +1 -0
- package/dist/esm/commands/app/tools/get-styles.js +36 -0
- package/dist/esm/commands/app/tools/get-styles.js.map +1 -0
- package/dist/esm/commands/app/tools/get-url.js +24 -0
- package/dist/esm/commands/app/tools/get-url.js.map +1 -0
- package/dist/esm/commands/app/tools/go-back.js +15 -0
- package/dist/esm/commands/app/tools/go-back.js.map +1 -0
- package/dist/esm/commands/app/tools/hover.js +24 -0
- package/dist/esm/commands/app/tools/hover.js.map +1 -0
- package/dist/esm/commands/app/tools/index.js +32 -0
- package/dist/esm/commands/app/tools/index.js.map +1 -0
- package/dist/esm/commands/app/tools/navigate.js +31 -0
- package/dist/esm/commands/app/tools/navigate.js.map +1 -0
- package/dist/esm/commands/app/tools/press-key.js +24 -0
- package/dist/esm/commands/app/tools/press-key.js.map +1 -0
- package/dist/esm/commands/app/tools/read-file.js +98 -0
- package/dist/esm/commands/app/tools/read-file.js.map +1 -0
- package/dist/esm/commands/app/tools/registry.js +34 -0
- package/dist/esm/commands/app/tools/registry.js.map +1 -0
- package/dist/esm/commands/app/tools/reload.js +15 -0
- package/dist/esm/commands/app/tools/reload.js.map +1 -0
- package/dist/esm/commands/app/tools/screenshot.js +133 -0
- package/dist/esm/commands/app/tools/screenshot.js.map +1 -0
- package/dist/esm/commands/app/tools/scroll.js +41 -0
- package/dist/esm/commands/app/tools/scroll.js.map +1 -0
- package/dist/esm/commands/app/tools/select.js +25 -0
- package/dist/esm/commands/app/tools/select.js.map +1 -0
- package/dist/esm/commands/app/tools/snapshot.js +24 -0
- package/dist/esm/commands/app/tools/snapshot.js.map +1 -0
- package/dist/esm/commands/app/tools/type-text.js +29 -0
- package/dist/esm/commands/app/tools/type-text.js.map +1 -0
- package/dist/esm/commands/app/tools/types.js +2 -0
- package/dist/esm/commands/app/tools/types.js.map +1 -0
- package/dist/esm/commands/app/tools/wait.js +39 -0
- package/dist/esm/commands/app/tools/wait.js.map +1 -0
- package/dist/esm/commands/app/tools/write-file.js +98 -0
- package/dist/esm/commands/app/tools/write-file.js.map +1 -0
- package/dist/esm/commands/app/types.js +2 -0
- package/dist/esm/commands/app/types.js.map +1 -0
- package/dist/esm/eval-resolve.js +83 -0
- package/dist/esm/eval-resolve.js.map +1 -0
- package/dist/esm/index.js +18 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/utils/agent-browser.js +67 -0
- package/dist/esm/utils/agent-browser.js.map +1 -0
- package/dist/esm/utils/browser-poll.js +26 -0
- package/dist/esm/utils/browser-poll.js.map +1 -0
- package/dist/esm/utils/daemon.js +83 -0
- package/dist/esm/utils/daemon.js.map +1 -0
- package/dist/esm/utils/index.js +6 -0
- package/dist/esm/utils/index.js.map +1 -0
- package/dist/esm/utils/process.js +30 -0
- package/dist/esm/utils/process.js.map +1 -0
- package/dist/esm/utils/server.js +65 -0
- package/dist/esm/utils/server.js.map +1 -0
- package/dist/esm/version.js +3 -0
- package/dist/esm/version.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types/commands/app/command.d.ts +7 -0
- package/dist/types/commands/app/eval.d.ts +9 -0
- package/dist/types/commands/app/format.d.ts +14 -0
- package/dist/types/commands/app/login.d.ts +14 -0
- package/dist/types/commands/app/prompts/execute-step.prompt.d.ts +13 -0
- package/dist/types/commands/app/prompts/judge.prompt.d.ts +15 -0
- package/dist/types/commands/app/prompts/plan.prompt.d.ts +13 -0
- package/dist/types/commands/app/prompts/step.prompt.d.ts +12 -0
- package/dist/types/commands/app/prompts/system.dev-server.prompt.d.ts +12 -0
- package/dist/types/commands/app/prompts/system.prompt.d.ts +12 -0
- package/dist/types/commands/app/server.d.ts +26 -0
- package/dist/types/commands/app/session-logger.d.ts +14 -0
- package/dist/types/commands/app/tools/click.d.ts +9 -0
- package/dist/types/commands/app/tools/errors.d.ts +9 -0
- package/dist/types/commands/app/tools/eval-js.d.ts +13 -0
- package/dist/types/commands/app/tools/fill.d.ts +9 -0
- package/dist/types/commands/app/tools/find.d.ts +9 -0
- package/dist/types/commands/app/tools/get-styles.d.ts +13 -0
- package/dist/types/commands/app/tools/get-url.d.ts +9 -0
- package/dist/types/commands/app/tools/go-back.d.ts +9 -0
- package/dist/types/commands/app/tools/hover.d.ts +9 -0
- package/dist/types/commands/app/tools/index.d.ts +9 -0
- package/dist/types/commands/app/tools/navigate.d.ts +9 -0
- package/dist/types/commands/app/tools/press-key.d.ts +9 -0
- package/dist/types/commands/app/tools/read-file.d.ts +13 -0
- package/dist/types/commands/app/tools/registry.d.ts +28 -0
- package/dist/types/commands/app/tools/reload.d.ts +9 -0
- package/dist/types/commands/app/tools/screenshot.d.ts +9 -0
- package/dist/types/commands/app/tools/scroll.d.ts +9 -0
- package/dist/types/commands/app/tools/select.d.ts +9 -0
- package/dist/types/commands/app/tools/snapshot.d.ts +9 -0
- package/dist/types/commands/app/tools/type-text.d.ts +9 -0
- package/dist/types/commands/app/tools/types.d.ts +12 -0
- package/dist/types/commands/app/tools/wait.d.ts +9 -0
- package/dist/types/commands/app/tools/write-file.d.ts +19 -0
- package/dist/types/commands/app/types.d.ts +68 -0
- package/dist/types/eval-resolve.d.ts +31 -0
- package/dist/types/index.d.ts +15 -0
- package/dist/types/utils/agent-browser.d.ts +26 -0
- package/dist/types/utils/browser-poll.d.ts +9 -0
- package/dist/types/utils/daemon.d.ts +16 -0
- package/dist/types/utils/index.d.ts +5 -0
- package/dist/types/utils/process.d.ts +21 -0
- package/dist/types/utils/server.d.ts +26 -0
- package/dist/types/version.d.ts +1 -0
- package/package.json +57 -0
- package/src/commands/app/command.ts +204 -0
- package/src/commands/app/eval.ts +114 -0
- package/src/commands/app/format.ts +110 -0
- package/src/commands/app/login.ts +92 -0
- package/src/commands/app/prompts/execute-step.prompt.ts +48 -0
- package/src/commands/app/prompts/judge.prompt.ts +121 -0
- package/src/commands/app/prompts/plan.prompt.ts +48 -0
- package/src/commands/app/prompts/step.prompt.ts +45 -0
- package/src/commands/app/prompts/system.dev-server.prompt.ts +22 -0
- package/src/commands/app/prompts/system.prompt.ts +78 -0
- package/src/commands/app/server.ts +105 -0
- package/src/commands/app/session-logger.ts +187 -0
- package/src/commands/app/tools/click.ts +28 -0
- package/src/commands/app/tools/errors.ts +26 -0
- package/src/commands/app/tools/eval-js.ts +40 -0
- package/src/commands/app/tools/fill.ts +29 -0
- package/src/commands/app/tools/find.ts +49 -0
- package/src/commands/app/tools/get-styles.ts +40 -0
- package/src/commands/app/tools/get-url.ts +26 -0
- package/src/commands/app/tools/go-back.ts +16 -0
- package/src/commands/app/tools/hover.ts +25 -0
- package/src/commands/app/tools/index.ts +57 -0
- package/src/commands/app/tools/navigate.ts +32 -0
- package/src/commands/app/tools/press-key.ts +25 -0
- package/src/commands/app/tools/read-file.ts +113 -0
- package/src/commands/app/tools/registry.ts +38 -0
- package/src/commands/app/tools/reload.ts +16 -0
- package/src/commands/app/tools/screenshot.ts +168 -0
- package/src/commands/app/tools/scroll.ts +45 -0
- package/src/commands/app/tools/select.ts +26 -0
- package/src/commands/app/tools/snapshot.ts +27 -0
- package/src/commands/app/tools/type-text.ts +30 -0
- package/src/commands/app/tools/types.ts +15 -0
- package/src/commands/app/tools/wait.ts +43 -0
- package/src/commands/app/tools/write-file.ts +104 -0
- package/src/commands/app/types.ts +76 -0
- package/src/eval-resolve.ts +113 -0
- package/src/index.ts +20 -0
- package/src/utils/agent-browser.ts +66 -0
- package/src/utils/browser-poll.ts +27 -0
- package/src/utils/daemon.ts +84 -0
- package/src/utils/index.ts +5 -0
- package/src/utils/process.ts +33 -0
- package/src/utils/server.ts +66 -0
- package/src/version.ts +2 -0
- package/tsconfig.json +13 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import { tryFormatMessage } from './format.js';
|
|
4
|
+
const TOOL_ICONS = {
|
|
5
|
+
browser_screenshot: '📷',
|
|
6
|
+
browser_navigate: '🌐',
|
|
7
|
+
browser_click: '👆',
|
|
8
|
+
browser_wait: '⏳',
|
|
9
|
+
browser_type: '⌨️',
|
|
10
|
+
browser_scroll: '📜',
|
|
11
|
+
browser_snapshot: '🔍',
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Attaches a console logger to a Copilot session that renders tool progress
|
|
15
|
+
* with a single shared ora spinner (avoiding concurrent-spinner warnings).
|
|
16
|
+
*
|
|
17
|
+
* @param session - The active Copilot SDK session
|
|
18
|
+
* @param options - Optional config (e.g. requested model name for mismatch detection)
|
|
19
|
+
* @returns A handle with `stop()` to tear down the spinner (e.g. on SIGINT)
|
|
20
|
+
*/
|
|
21
|
+
export function attachSessionLogger(session, options) {
|
|
22
|
+
const pendingTools = new Map();
|
|
23
|
+
let spinner = null;
|
|
24
|
+
function syncSpinner() {
|
|
25
|
+
if (pendingTools.size === 0) {
|
|
26
|
+
if (spinner) {
|
|
27
|
+
spinner.stop();
|
|
28
|
+
spinner = null;
|
|
29
|
+
}
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const text = [...pendingTools.values()].join(chalk.dim(' | '));
|
|
33
|
+
if (spinner) {
|
|
34
|
+
spinner.text = text;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
spinner = ora({ text, color: 'cyan' }).start();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function pauseSpinner() {
|
|
41
|
+
if (spinner) {
|
|
42
|
+
spinner.stop();
|
|
43
|
+
spinner = null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function logCompletion(label, ok) {
|
|
47
|
+
pauseSpinner();
|
|
48
|
+
const prefix = ok ? chalk.green('✔') : chalk.red('✖');
|
|
49
|
+
console.log(`${prefix} ${label}`);
|
|
50
|
+
syncSpinner();
|
|
51
|
+
}
|
|
52
|
+
session.on((event) => {
|
|
53
|
+
switch (event.type) {
|
|
54
|
+
case 'tool.execution_start': {
|
|
55
|
+
const { toolCallId, toolName, arguments: args } = event.data;
|
|
56
|
+
const detail = args?.url ?? args?.path ?? args?.load ?? args?.selector;
|
|
57
|
+
const icon = TOOL_ICONS[toolName] ?? '🔧';
|
|
58
|
+
const label = typeof detail === 'string' ? `${icon} ${toolName} (${detail})` : `${icon} ${toolName}`;
|
|
59
|
+
pendingTools.set(toolCallId, label);
|
|
60
|
+
syncSpinner();
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
case 'tool.execution_complete': {
|
|
64
|
+
const label = pendingTools.get(event.data.toolCallId);
|
|
65
|
+
if (label) {
|
|
66
|
+
pendingTools.delete(event.data.toolCallId);
|
|
67
|
+
logCompletion(label, event.data.success);
|
|
68
|
+
}
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
case 'external_tool.completed': {
|
|
72
|
+
const label = pendingTools.get(event.data.requestId);
|
|
73
|
+
if (label) {
|
|
74
|
+
pendingTools.delete(event.data.requestId);
|
|
75
|
+
logCompletion(label, true);
|
|
76
|
+
}
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
case 'assistant.reasoning': {
|
|
80
|
+
pauseSpinner();
|
|
81
|
+
console.log(chalk.dim(`🧠 ${event.data.content}`));
|
|
82
|
+
syncSpinner();
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
case 'assistant.message': {
|
|
86
|
+
if (event.data.content) {
|
|
87
|
+
pauseSpinner();
|
|
88
|
+
const formatted = tryFormatMessage(event.data.content);
|
|
89
|
+
if (formatted) {
|
|
90
|
+
console.log(formatted);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
console.log(chalk.green(`🤖 ${event.data.content}`));
|
|
94
|
+
}
|
|
95
|
+
syncSpinner();
|
|
96
|
+
}
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
case 'permission.requested': {
|
|
100
|
+
const { requestId, permissionRequest } = event.data;
|
|
101
|
+
const toolName = permissionRequest.kind === 'custom-tool'
|
|
102
|
+
? permissionRequest.toolName
|
|
103
|
+
: permissionRequest.kind;
|
|
104
|
+
pendingTools.set(requestId, `🔐 ${toolName}`);
|
|
105
|
+
syncSpinner();
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
case 'permission.completed': {
|
|
109
|
+
const label = pendingTools.get(event.data.requestId);
|
|
110
|
+
if (label) {
|
|
111
|
+
const approved = event.data.result?.kind === 'approved';
|
|
112
|
+
pendingTools.delete(event.data.requestId);
|
|
113
|
+
logCompletion(label, approved);
|
|
114
|
+
}
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
// @ts-expect-error - missing case types in SDK typings
|
|
118
|
+
case 'session.tools_updated': {
|
|
119
|
+
// @ts-expect-error - model property missing in SDK typings
|
|
120
|
+
const negotiatedModel = event.data.model;
|
|
121
|
+
if (negotiatedModel) {
|
|
122
|
+
console.log(chalk.dim(`💾 ${negotiatedModel}`));
|
|
123
|
+
if (options?.requestedModel && negotiatedModel !== options.requestedModel) {
|
|
124
|
+
console.log(chalk.yellow(`⚠️ Requested model "${options.requestedModel}" but server negotiated "${negotiatedModel}"`));
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
case 'external_tool.requested':
|
|
130
|
+
case 'user.message': {
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
case 'assistant.message_delta':
|
|
134
|
+
case 'assistant.reasoning_delta':
|
|
135
|
+
case 'assistant.streaming_delta':
|
|
136
|
+
case 'assistant.turn_start':
|
|
137
|
+
case 'assistant.turn_end':
|
|
138
|
+
case 'assistant.usage':
|
|
139
|
+
case 'pending_messages.modified':
|
|
140
|
+
case 'session.idle':
|
|
141
|
+
case 'session.usage_info': {
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
case 'session.info': {
|
|
145
|
+
const { message } = event.data;
|
|
146
|
+
if (message) {
|
|
147
|
+
pauseSpinner();
|
|
148
|
+
console.log(chalk.dim(`ℹ️ ${message}`));
|
|
149
|
+
syncSpinner();
|
|
150
|
+
}
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
case 'assistant.intent': {
|
|
154
|
+
const { intent } = event.data;
|
|
155
|
+
if (intent) {
|
|
156
|
+
pauseSpinner();
|
|
157
|
+
console.log(chalk.yellow(`🎯 ${intent}`));
|
|
158
|
+
syncSpinner();
|
|
159
|
+
}
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
default:
|
|
163
|
+
console.log(event);
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
return {
|
|
168
|
+
stop: () => pauseSpinner(),
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=session-logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-logger.js","sourceRoot":"","sources":["../../../../src/commands/app/session-logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates the click interaction tool.
|
|
3
|
+
*
|
|
4
|
+
* @param context - Shared browser tool execution context
|
|
5
|
+
* @param defineTool - Copilot SDK helper used to declare tools
|
|
6
|
+
* @returns Copilot tool definition for clicking a page element
|
|
7
|
+
*/
|
|
8
|
+
export function createClickTool(context, defineTool) {
|
|
9
|
+
return defineTool('browser_click', {
|
|
10
|
+
description: 'Click an element identified by a ref (@e1), CSS selector, or text selector.',
|
|
11
|
+
parameters: {
|
|
12
|
+
type: 'object',
|
|
13
|
+
properties: {
|
|
14
|
+
target: {
|
|
15
|
+
type: 'string',
|
|
16
|
+
description: 'Element ref (e.g. @e3), CSS selector, or text selector',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
required: ['target'],
|
|
20
|
+
},
|
|
21
|
+
handler: async (args) => {
|
|
22
|
+
const { target } = args;
|
|
23
|
+
return context.invoke(['click', target]);
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=click.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"click.js","sourceRoot":"","sources":["../../../../../src/commands/app/tools/click.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,OAAgC,EAAE,UAAsB;IACtF,OAAO,UAAU,CAAC,eAAe,EAAE;QACjC,WAAW,EAAE,6EAA6E;QAC1F,UAAU,EAAE;YACV,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE;gBACV,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,wDAAwD;iBACtE;aACF;YACD,QAAQ,EAAE,CAAC,QAAQ,CAAC;SACrB;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACtB,MAAM,EAAE,MAAM,EAAE,GAAG,IAA0B,CAAC;YAC9C,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;QAC3C,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { writeFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Creates the browser error collection tool.
|
|
5
|
+
*
|
|
6
|
+
* @param context - Shared browser tool execution context
|
|
7
|
+
* @param defineTool - Copilot SDK helper used to declare tools
|
|
8
|
+
* @returns Copilot tool definition for retrieving JavaScript errors
|
|
9
|
+
*/
|
|
10
|
+
export function createErrorsTool(context, defineTool) {
|
|
11
|
+
return defineTool('browser_errors', {
|
|
12
|
+
description: 'Get all JavaScript console errors from the browser.',
|
|
13
|
+
parameters: {
|
|
14
|
+
type: 'object',
|
|
15
|
+
properties: {},
|
|
16
|
+
},
|
|
17
|
+
handler: async () => {
|
|
18
|
+
const output = context.invoke(['errors']);
|
|
19
|
+
writeFileSync(join(context.outDir, 'errors.txt'), output, 'utf-8');
|
|
20
|
+
return output || 'No errors';
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../../../src/commands/app/tools/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAIjC;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAgC,EAAE,UAAsB;IACvF,OAAO,UAAU,CAAC,gBAAgB,EAAE;QAClC,WAAW,EAAE,qDAAqD;QAClE,UAAU,EAAE;YACV,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE,EAAE;SACf;QACD,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC1C,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;YACnE,OAAO,MAAM,IAAI,WAAW,CAAC;QAC/B,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { writeFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Creates the JavaScript evaluation tool.
|
|
5
|
+
*
|
|
6
|
+
* Runs a JS expression in the browser's page context and returns the result.
|
|
7
|
+
* Ideal for extracting computed values such as `getComputedStyle(document.body).backgroundColor`
|
|
8
|
+
* that cannot be reliably inferred from screenshots.
|
|
9
|
+
*
|
|
10
|
+
* @param context - Shared browser tool execution context
|
|
11
|
+
* @param defineTool - Copilot SDK helper used to declare tools
|
|
12
|
+
* @returns Copilot tool definition for evaluating arbitrary JavaScript in the browser
|
|
13
|
+
*/
|
|
14
|
+
export function createEvalJsTool(context, defineTool) {
|
|
15
|
+
return defineTool('browser_eval', {
|
|
16
|
+
description: 'Evaluate a JavaScript expression in the browser page context and return the result. Use for reading DOM values, computed styles, or element properties that need exact values (e.g. getComputedStyle(document.body).backgroundColor).',
|
|
17
|
+
parameters: {
|
|
18
|
+
type: 'object',
|
|
19
|
+
properties: {
|
|
20
|
+
script: {
|
|
21
|
+
type: 'string',
|
|
22
|
+
description: 'A single JavaScript expression to evaluate (e.g. "getComputedStyle(document.body).backgroundColor")',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
required: ['script'],
|
|
26
|
+
},
|
|
27
|
+
handler: async (args) => {
|
|
28
|
+
const { script } = args;
|
|
29
|
+
const output = context.invoke(['eval', script, '--json']);
|
|
30
|
+
const timestamp = Date.now();
|
|
31
|
+
writeFileSync(join(context.outDir, `eval-${timestamp}.json`), output, 'utf-8');
|
|
32
|
+
return output;
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=eval-js.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eval-js.js","sourceRoot":"","sources":["../../../../../src/commands/app/tools/eval-js.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAIjC;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAgC,EAAE,UAAsB;IACvF,OAAO,UAAU,CAAC,cAAc,EAAE;QAChC,WAAW,EACT,uOAAuO;QACzO,UAAU,EAAE;YACV,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE;gBACV,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,WAAW,EACT,qGAAqG;iBACxG;aACF;YACD,QAAQ,EAAE,CAAC,QAAQ,CAAC;SACrB;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACtB,MAAM,EAAE,MAAM,EAAE,GAAG,IAA0B,CAAC;YAC9C,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;YAC1D,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC7B,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,SAAS,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;YAC/E,OAAO,MAAM,CAAC;QAChB,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates the form fill tool.
|
|
3
|
+
*
|
|
4
|
+
* @param context - Shared browser tool execution context
|
|
5
|
+
* @param defineTool - Copilot SDK helper used to declare tools
|
|
6
|
+
* @returns Copilot tool definition for filling input fields
|
|
7
|
+
*/
|
|
8
|
+
export function createFillTool(context, defineTool) {
|
|
9
|
+
return defineTool('browser_fill', {
|
|
10
|
+
description: 'Fill a form field with text. Clears existing content first.',
|
|
11
|
+
parameters: {
|
|
12
|
+
type: 'object',
|
|
13
|
+
properties: {
|
|
14
|
+
target: {
|
|
15
|
+
type: 'string',
|
|
16
|
+
description: 'Element ref or CSS selector for the input field',
|
|
17
|
+
},
|
|
18
|
+
value: { type: 'string', description: 'Text to fill into the field' },
|
|
19
|
+
},
|
|
20
|
+
required: ['target', 'value'],
|
|
21
|
+
},
|
|
22
|
+
handler: async (args) => {
|
|
23
|
+
const { target, value } = args;
|
|
24
|
+
return context.invoke(['fill', target, value]);
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=fill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fill.js","sourceRoot":"","sources":["../../../../../src/commands/app/tools/fill.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,OAAgC,EAAE,UAAsB;IACrF,OAAO,UAAU,CAAC,cAAc,EAAE;QAChC,WAAW,EAAE,6DAA6D;QAC1E,UAAU,EAAE;YACV,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE;gBACV,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,iDAAiD;iBAC/D;gBACD,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,6BAA6B,EAAE;aACtE;YACD,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC;SAC9B;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACtB,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,IAAyC,CAAC;YACpE,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;QACjD,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates the semantic locator tool.
|
|
3
|
+
*
|
|
4
|
+
* @param context - Shared browser tool execution context
|
|
5
|
+
* @param defineTool - Copilot SDK helper used to declare tools
|
|
6
|
+
* @returns Copilot tool definition for semantic element lookup and optional action execution
|
|
7
|
+
*/
|
|
8
|
+
export function createFindTool(context, defineTool) {
|
|
9
|
+
return defineTool('browser_find', {
|
|
10
|
+
description: 'Find an element using semantic locators (role, text, label) and optionally perform an action on it.',
|
|
11
|
+
parameters: {
|
|
12
|
+
type: 'object',
|
|
13
|
+
properties: {
|
|
14
|
+
by: {
|
|
15
|
+
type: 'string',
|
|
16
|
+
description: 'Locator type: "role", "text", or "label"',
|
|
17
|
+
},
|
|
18
|
+
value: {
|
|
19
|
+
type: 'string',
|
|
20
|
+
description: 'Value to search for (role name, text content, or label)',
|
|
21
|
+
},
|
|
22
|
+
action: {
|
|
23
|
+
type: 'string',
|
|
24
|
+
description: 'Action to perform: "click" or "fill"',
|
|
25
|
+
},
|
|
26
|
+
name: { type: 'string', description: 'Accessible name filter (for role locators)' },
|
|
27
|
+
fillValue: { type: 'string', description: 'Text to fill (when action is "fill")' },
|
|
28
|
+
},
|
|
29
|
+
required: ['by', 'value'],
|
|
30
|
+
},
|
|
31
|
+
handler: async (args) => {
|
|
32
|
+
const { by, value, action, name, fillValue } = args;
|
|
33
|
+
const command = ['find', by, value];
|
|
34
|
+
if (action)
|
|
35
|
+
command.push(action);
|
|
36
|
+
if (name)
|
|
37
|
+
command.push('--name', name);
|
|
38
|
+
if (fillValue)
|
|
39
|
+
command.push(fillValue);
|
|
40
|
+
return context.invoke(command);
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=find.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find.js","sourceRoot":"","sources":["../../../../../src/commands/app/tools/find.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,OAAgC,EAAE,UAAsB;IACrF,OAAO,UAAU,CAAC,cAAc,EAAE;QAChC,WAAW,EACT,qGAAqG;QACvG,UAAU,EAAE;YACV,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE;gBACV,EAAE,EAAE;oBACF,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,0CAA0C;iBACxD;gBACD,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,yDAAyD;iBACvE;gBACD,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,sCAAsC;iBACpD;gBACD,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,4CAA4C,EAAE;gBACnF,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sCAAsC,EAAE;aACnF;YACD,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC;SAC1B;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACtB,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,IAM9C,CAAC;YACF,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;YACpC,IAAI,MAAM;gBAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACjC,IAAI,IAAI;gBAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YACvC,IAAI,SAAS;gBAAE,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACvC,OAAO,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { writeFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Creates the computed CSS styles inspection tool.
|
|
5
|
+
*
|
|
6
|
+
* Use this tool instead of (or alongside) screenshots to verify color and layout criteria.
|
|
7
|
+
* It returns the actual browser-computed style values for a given selector, which cannot
|
|
8
|
+
* be misread or hallucinated the way image data can.
|
|
9
|
+
*
|
|
10
|
+
* @param context - Shared browser tool execution context
|
|
11
|
+
* @param defineTool - Copilot SDK helper used to declare tools
|
|
12
|
+
* @returns Copilot tool definition for retrieving computed CSS style properties
|
|
13
|
+
*/
|
|
14
|
+
export function createGetStylesTool(context, defineTool) {
|
|
15
|
+
return defineTool('browser_get_styles', {
|
|
16
|
+
description: 'Get computed CSS styles of an element. Use this for verifying visual properties such as background-color, color, or font-size WITHOUT relying on screenshot interpretation. Returns the computed style object as plain text.',
|
|
17
|
+
parameters: {
|
|
18
|
+
type: 'object',
|
|
19
|
+
properties: {
|
|
20
|
+
selector: {
|
|
21
|
+
type: 'string',
|
|
22
|
+
description: 'Element ref (e.g. @e1), CSS selector, or tag name to inspect (e.g. "body", "main", "h1")',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
required: ['selector'],
|
|
26
|
+
},
|
|
27
|
+
handler: async (args) => {
|
|
28
|
+
const { selector } = args;
|
|
29
|
+
const output = context.invoke(['get', 'styles', selector]);
|
|
30
|
+
const safeSelector = selector.replace(/[^a-z0-9]/gi, '_').slice(0, 40);
|
|
31
|
+
writeFileSync(join(context.outDir, `styles-${safeSelector}.txt`), output, 'utf-8');
|
|
32
|
+
return output;
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=get-styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-styles.js","sourceRoot":"","sources":["../../../../../src/commands/app/tools/get-styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAIjC;;;;;;;;;;GAUG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAgC,EAAE,UAAsB;IAC1F,OAAO,UAAU,CAAC,oBAAoB,EAAE;QACtC,WAAW,EACT,8NAA8N;QAChO,UAAU,EAAE;YACV,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE;gBACV,QAAQ,EAAE;oBACR,IAAI,EAAE,QAAQ;oBACd,WAAW,EACT,0FAA0F;iBAC7F;aACF;YACD,QAAQ,EAAE,CAAC,UAAU,CAAC;SACvB;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACtB,MAAM,EAAE,QAAQ,EAAE,GAAG,IAA4B,CAAC;YAClD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;YAC3D,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACvE,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,UAAU,YAAY,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;YACnF,OAAO,MAAM,CAAC;QAChB,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { writeFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Creates the current URL inspection tool.
|
|
5
|
+
*
|
|
6
|
+
* @param context - Shared browser tool execution context
|
|
7
|
+
* @param defineTool - Copilot SDK helper used to declare tools
|
|
8
|
+
* @returns Copilot tool definition for retrieving the current page URL
|
|
9
|
+
*/
|
|
10
|
+
export function createGetUrlTool(context, defineTool) {
|
|
11
|
+
return defineTool('browser_get_url', {
|
|
12
|
+
description: 'Get the current page URL.',
|
|
13
|
+
parameters: {
|
|
14
|
+
type: 'object',
|
|
15
|
+
properties: {},
|
|
16
|
+
},
|
|
17
|
+
handler: async () => {
|
|
18
|
+
const output = context.invoke(['get', 'url']);
|
|
19
|
+
writeFileSync(join(context.outDir, 'url.txt'), output, 'utf-8');
|
|
20
|
+
return output;
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=get-url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-url.js","sourceRoot":"","sources":["../../../../../src/commands/app/tools/get-url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAIjC;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAgC,EAAE,UAAsB;IACvF,OAAO,UAAU,CAAC,iBAAiB,EAAE;QACnC,WAAW,EAAE,2BAA2B;QACxC,UAAU,EAAE;YACV,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE,EAAE;SACf;QACD,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;YAC9C,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;YAChE,OAAO,MAAM,CAAC;QAChB,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates the back navigation tool.
|
|
3
|
+
*
|
|
4
|
+
* @param context - Shared browser tool execution context
|
|
5
|
+
* @param defineTool - Copilot SDK helper used to declare tools
|
|
6
|
+
* @returns Copilot tool definition for going back in browser history
|
|
7
|
+
*/
|
|
8
|
+
export function createGoBackTool(context, defineTool) {
|
|
9
|
+
return defineTool('browser_go_back', {
|
|
10
|
+
description: 'Navigate back in browser history.',
|
|
11
|
+
parameters: { type: 'object', properties: {} },
|
|
12
|
+
handler: async () => context.invoke(['back']),
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=go-back.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"go-back.js","sourceRoot":"","sources":["../../../../../src/commands/app/tools/go-back.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAgC,EAAE,UAAsB;IACvF,OAAO,UAAU,CAAC,iBAAiB,EAAE;QACnC,WAAW,EAAE,mCAAmC;QAChD,UAAU,EAAE,EAAE,IAAI,EAAE,QAAiB,EAAE,UAAU,EAAE,EAAE,EAAE;QACvD,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;KAC9C,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates the hover interaction tool.
|
|
3
|
+
*
|
|
4
|
+
* @param context - Shared browser tool execution context
|
|
5
|
+
* @param defineTool - Copilot SDK helper used to declare tools
|
|
6
|
+
* @returns Copilot tool definition for hovering a page element
|
|
7
|
+
*/
|
|
8
|
+
export function createHoverTool(context, defineTool) {
|
|
9
|
+
return defineTool('browser_hover', {
|
|
10
|
+
description: 'Hover over an element.',
|
|
11
|
+
parameters: {
|
|
12
|
+
type: 'object',
|
|
13
|
+
properties: {
|
|
14
|
+
target: { type: 'string', description: 'Element ref or CSS selector' },
|
|
15
|
+
},
|
|
16
|
+
required: ['target'],
|
|
17
|
+
},
|
|
18
|
+
handler: async (args) => {
|
|
19
|
+
const { target } = args;
|
|
20
|
+
return context.invoke(['hover', target]);
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=hover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hover.js","sourceRoot":"","sources":["../../../../../src/commands/app/tools/hover.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,OAAgC,EAAE,UAAsB;IACtF,OAAO,UAAU,CAAC,eAAe,EAAE;QACjC,WAAW,EAAE,wBAAwB;QACrC,UAAU,EAAE;YACV,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE;gBACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,6BAA6B,EAAE;aACvE;YACD,QAAQ,EAAE,CAAC,QAAQ,CAAC;SACrB;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACtB,MAAM,EAAE,MAAM,EAAE,GAAG,IAA0B,CAAC;YAC9C,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;QAC3C,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { createClickTool } from './click.js';
|
|
2
|
+
import { createErrorsTool } from './errors.js';
|
|
3
|
+
import { createFillTool } from './fill.js';
|
|
4
|
+
import { createFindTool } from './find.js';
|
|
5
|
+
import { createGetUrlTool } from './get-url.js';
|
|
6
|
+
import { createGoBackTool } from './go-back.js';
|
|
7
|
+
import { createHoverTool } from './hover.js';
|
|
8
|
+
import { createNavigateTool } from './navigate.js';
|
|
9
|
+
import { createPressKeyTool } from './press-key.js';
|
|
10
|
+
import { createReloadTool } from './reload.js';
|
|
11
|
+
import { createEvalJsTool } from './eval-js.js';
|
|
12
|
+
import { createGetStylesTool } from './get-styles.js';
|
|
13
|
+
import { AgentBrowserToolRegistry } from './registry.js';
|
|
14
|
+
import { createScreenshotTool } from './screenshot.js';
|
|
15
|
+
import { createScrollTool } from './scroll.js';
|
|
16
|
+
import { createSelectTool } from './select.js';
|
|
17
|
+
import { createSnapshotTool } from './snapshot.js';
|
|
18
|
+
import { createTypeTextTool } from './type-text.js';
|
|
19
|
+
import { createWaitTool } from './wait.js';
|
|
20
|
+
/**
|
|
21
|
+
* Creates the full set of Copilot browser tools for an eval session.
|
|
22
|
+
*
|
|
23
|
+
* @param context - Shared execution context for all browser tool wrappers
|
|
24
|
+
* @param defineTool - Copilot SDK helper used to declare tools
|
|
25
|
+
* @returns Registered browser tools in the order they should be exposed to the model
|
|
26
|
+
*/
|
|
27
|
+
export function createAgentBrowserTools(context, defineTool) {
|
|
28
|
+
const agentBrowser = new AgentBrowserToolRegistry();
|
|
29
|
+
agentBrowser.addTools(createNavigateTool(context, defineTool), createSnapshotTool(context, defineTool), createScreenshotTool(context, defineTool), createGetStylesTool(context, defineTool), createEvalJsTool(context, defineTool), createClickTool(context, defineTool), createFillTool(context, defineTool), createTypeTextTool(context, defineTool), createPressKeyTool(context, defineTool), createHoverTool(context, defineTool), createSelectTool(context, defineTool), createScrollTool(context, defineTool), createWaitTool(context, defineTool), createFindTool(context, defineTool), createErrorsTool(context, defineTool), createGetUrlTool(context, defineTool), createGoBackTool(context, defineTool), createReloadTool(context, defineTool));
|
|
30
|
+
return agentBrowser.getTools();
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/commands/app/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEpD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE3C;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CACrC,OAAgC,EAChC,UAAsB;IAEtB,MAAM,YAAY,GAAG,IAAI,wBAAwB,EAAE,CAAC;IAEpD,YAAY,CAAC,QAAQ,CACnB,kBAAkB,CAAC,OAAO,EAAE,UAAU,CAAC,EACvC,kBAAkB,CAAC,OAAO,EAAE,UAAU,CAAC,EACvC,oBAAoB,CAAC,OAAO,EAAE,UAAU,CAAC,EACzC,mBAAmB,CAAC,OAAO,EAAE,UAAU,CAAC,EACxC,gBAAgB,CAAC,OAAO,EAAE,UAAU,CAAC,EACrC,eAAe,CAAC,OAAO,EAAE,UAAU,CAAC,EACpC,cAAc,CAAC,OAAO,EAAE,UAAU,CAAC,EACnC,kBAAkB,CAAC,OAAO,EAAE,UAAU,CAAC,EACvC,kBAAkB,CAAC,OAAO,EAAE,UAAU,CAAC,EACvC,eAAe,CAAC,OAAO,EAAE,UAAU,CAAC,EACpC,gBAAgB,CAAC,OAAO,EAAE,UAAU,CAAC,EACrC,gBAAgB,CAAC,OAAO,EAAE,UAAU,CAAC,EACrC,cAAc,CAAC,OAAO,EAAE,UAAU,CAAC,EACnC,cAAc,CAAC,OAAO,EAAE,UAAU,CAAC,EACnC,gBAAgB,CAAC,OAAO,EAAE,UAAU,CAAC,EACrC,gBAAgB,CAAC,OAAO,EAAE,UAAU,CAAC,EACrC,gBAAgB,CAAC,OAAO,EAAE,UAAU,CAAC,EACrC,gBAAgB,CAAC,OAAO,EAAE,UAAU,CAAC,CACtC,CAAC;IAEF,OAAO,YAAY,CAAC,QAAQ,EAAE,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { clearMsalInteraction } from '../../../utils/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates the browser navigation tool.
|
|
4
|
+
*
|
|
5
|
+
* @param context - Shared browser tool execution context
|
|
6
|
+
* @param defineTool - Copilot SDK helper used to declare tools
|
|
7
|
+
* @returns Copilot tool definition for opening a URL
|
|
8
|
+
*/
|
|
9
|
+
export function createNavigateTool(context, defineTool) {
|
|
10
|
+
return defineTool('browser_navigate', {
|
|
11
|
+
description: 'Navigate the browser to a URL. Use this to open the application or follow links.',
|
|
12
|
+
parameters: {
|
|
13
|
+
type: 'object',
|
|
14
|
+
properties: {
|
|
15
|
+
url: { type: 'string', description: 'The URL to navigate to' },
|
|
16
|
+
},
|
|
17
|
+
required: ['url'],
|
|
18
|
+
},
|
|
19
|
+
handler: async (args) => {
|
|
20
|
+
const { url } = args;
|
|
21
|
+
try {
|
|
22
|
+
const result = context.invoke(['open', url], 120_000);
|
|
23
|
+
return result || 'Navigation complete';
|
|
24
|
+
}
|
|
25
|
+
finally {
|
|
26
|
+
clearMsalInteraction();
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=navigate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigate.js","sourceRoot":"","sources":["../../../../../src/commands/app/tools/navigate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAI/D;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAgC,EAAE,UAAsB;IACzF,OAAO,UAAU,CAAC,kBAAkB,EAAE;QACpC,WAAW,EAAE,kFAAkF;QAC/F,UAAU,EAAE;YACV,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE;gBACV,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,wBAAwB,EAAE;aAC/D;YACD,QAAQ,EAAE,CAAC,KAAK,CAAC;SAClB;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACtB,MAAM,EAAE,GAAG,EAAE,GAAG,IAAuB,CAAC;YACxC,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;gBACtD,OAAO,MAAM,IAAI,qBAAqB,CAAC;YACzC,CAAC;oBAAS,CAAC;gBACT,oBAAoB,EAAE,CAAC;YACzB,CAAC;QACH,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates the keyboard press tool.
|
|
3
|
+
*
|
|
4
|
+
* @param context - Shared browser tool execution context
|
|
5
|
+
* @param defineTool - Copilot SDK helper used to declare tools
|
|
6
|
+
* @returns Copilot tool definition for pressing a single key
|
|
7
|
+
*/
|
|
8
|
+
export function createPressKeyTool(context, defineTool) {
|
|
9
|
+
return defineTool('browser_press_key', {
|
|
10
|
+
description: 'Press a keyboard key (Enter, Tab, Escape, ArrowDown, etc.).',
|
|
11
|
+
parameters: {
|
|
12
|
+
type: 'object',
|
|
13
|
+
properties: {
|
|
14
|
+
key: { type: 'string', description: 'Key name (e.g. Enter, Tab, Escape)' },
|
|
15
|
+
},
|
|
16
|
+
required: ['key'],
|
|
17
|
+
},
|
|
18
|
+
handler: async (args) => {
|
|
19
|
+
const { key } = args;
|
|
20
|
+
return context.invoke(['press', key]);
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=press-key.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"press-key.js","sourceRoot":"","sources":["../../../../../src/commands/app/tools/press-key.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAgC,EAAE,UAAsB;IACzF,OAAO,UAAU,CAAC,mBAAmB,EAAE;QACrC,WAAW,EAAE,6DAA6D;QAC1E,UAAU,EAAE;YACV,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE;gBACV,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oCAAoC,EAAE;aAC3E;YACD,QAAQ,EAAE,CAAC,KAAK,CAAC;SAClB;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACtB,MAAM,EAAE,GAAG,EAAE,GAAG,IAAuB,CAAC;YACxC,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;QACxC,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|