@push.rocks/smartagent 1.0.2
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/dist_ts/00_commitinfo_data.d.ts +8 -0
- package/dist_ts/00_commitinfo_data.js +9 -0
- package/dist_ts/index.d.ts +10 -0
- package/dist_ts/index.js +18 -0
- package/dist_ts/plugins.d.ts +6 -0
- package/dist_ts/plugins.js +8 -0
- package/dist_ts/smartagent.classes.driveragent.d.ts +70 -0
- package/dist_ts/smartagent.classes.driveragent.js +274 -0
- package/dist_ts/smartagent.classes.dualagent.d.ts +62 -0
- package/dist_ts/smartagent.classes.dualagent.js +298 -0
- package/dist_ts/smartagent.classes.guardianagent.d.ts +46 -0
- package/dist_ts/smartagent.classes.guardianagent.js +201 -0
- package/dist_ts/smartagent.classes.smartagent.d.ts +123 -0
- package/dist_ts/smartagent.classes.smartagent.js +274 -0
- package/dist_ts/smartagent.interfaces.d.ts +165 -0
- package/dist_ts/smartagent.interfaces.js +8 -0
- package/dist_ts/smartagent.tools.base.d.ts +46 -0
- package/dist_ts/smartagent.tools.base.js +45 -0
- package/dist_ts/smartagent.tools.browser.d.ts +16 -0
- package/dist_ts/smartagent.tools.browser.js +177 -0
- package/dist_ts/smartagent.tools.filesystem.d.ts +16 -0
- package/dist_ts/smartagent.tools.filesystem.js +352 -0
- package/dist_ts/smartagent.tools.http.d.ts +15 -0
- package/dist_ts/smartagent.tools.http.js +187 -0
- package/dist_ts/smartagent.tools.shell.d.ts +16 -0
- package/dist_ts/smartagent.tools.shell.js +155 -0
- package/npmextra.json +18 -0
- package/package.json +50 -0
- package/readme.hints.md +16 -0
- package/readme.md +299 -0
- package/ts/00_commitinfo_data.ts +8 -0
- package/ts/index.ts +29 -0
- package/ts/plugins.ts +14 -0
- package/ts/smartagent.classes.driveragent.ts +321 -0
- package/ts/smartagent.classes.dualagent.ts +350 -0
- package/ts/smartagent.classes.guardianagent.ts +241 -0
- package/ts/smartagent.interfaces.ts +210 -0
- package/ts/smartagent.tools.base.ts +80 -0
- package/ts/smartagent.tools.browser.ts +200 -0
- package/ts/smartagent.tools.filesystem.ts +379 -0
- package/ts/smartagent.tools.http.ts +205 -0
- package/ts/smartagent.tools.shell.ts +182 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
|
|
3
|
+
// ================================
|
|
4
|
+
// Agent Configuration Interfaces
|
|
5
|
+
// ================================
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Configuration options for the DualAgentOrchestrator
|
|
9
|
+
*/
|
|
10
|
+
export interface IDualAgentOptions extends plugins.smartai.ISmartAiOptions {
|
|
11
|
+
/** Name of the agent system */
|
|
12
|
+
name?: string;
|
|
13
|
+
/** Default AI provider for both Driver and Guardian */
|
|
14
|
+
defaultProvider?: plugins.smartai.TProvider;
|
|
15
|
+
/** Optional separate provider for Guardian (for cost optimization) */
|
|
16
|
+
guardianProvider?: plugins.smartai.TProvider;
|
|
17
|
+
/** System message for the Driver agent */
|
|
18
|
+
driverSystemMessage?: string;
|
|
19
|
+
/** Policy prompt for the Guardian agent - REQUIRED */
|
|
20
|
+
guardianPolicyPrompt: string;
|
|
21
|
+
/** Maximum iterations for task completion (default: 20) */
|
|
22
|
+
maxIterations?: number;
|
|
23
|
+
/** Maximum consecutive rejections before aborting (default: 3) */
|
|
24
|
+
maxConsecutiveRejections?: number;
|
|
25
|
+
/** Enable verbose logging */
|
|
26
|
+
verbose?: boolean;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// ================================
|
|
30
|
+
// Message Interfaces
|
|
31
|
+
// ================================
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Represents a message in the agent's conversation history
|
|
35
|
+
*/
|
|
36
|
+
export interface IAgentMessage {
|
|
37
|
+
role: 'system' | 'user' | 'assistant' | 'tool' | 'guardian';
|
|
38
|
+
content: string;
|
|
39
|
+
toolName?: string;
|
|
40
|
+
toolResult?: unknown;
|
|
41
|
+
toolCall?: IToolCallProposal;
|
|
42
|
+
guardianDecision?: IGuardianDecision;
|
|
43
|
+
timestamp?: Date;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ================================
|
|
47
|
+
// Tool Interfaces
|
|
48
|
+
// ================================
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Represents an action that a tool can perform
|
|
52
|
+
*/
|
|
53
|
+
export interface IToolAction {
|
|
54
|
+
/** Action name (e.g., 'read', 'write', 'delete') */
|
|
55
|
+
name: string;
|
|
56
|
+
/** Description of what this action does */
|
|
57
|
+
description: string;
|
|
58
|
+
/** JSON schema for action parameters */
|
|
59
|
+
parameters: Record<string, unknown>;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Proposed tool call from the Driver
|
|
64
|
+
*/
|
|
65
|
+
export interface IToolCallProposal {
|
|
66
|
+
/** Unique ID for this proposal */
|
|
67
|
+
proposalId: string;
|
|
68
|
+
/** Name of the tool */
|
|
69
|
+
toolName: string;
|
|
70
|
+
/** Specific action to perform */
|
|
71
|
+
action: string;
|
|
72
|
+
/** Parameters for the action */
|
|
73
|
+
params: Record<string, unknown>;
|
|
74
|
+
/** Driver's reasoning for this call */
|
|
75
|
+
reasoning?: string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Result of tool execution
|
|
80
|
+
*/
|
|
81
|
+
export interface IToolExecutionResult {
|
|
82
|
+
success: boolean;
|
|
83
|
+
result?: unknown;
|
|
84
|
+
error?: string;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Base interface for wrapped tools
|
|
89
|
+
*/
|
|
90
|
+
export interface IAgentToolWrapper {
|
|
91
|
+
/** Tool name */
|
|
92
|
+
name: string;
|
|
93
|
+
/** Tool description */
|
|
94
|
+
description: string;
|
|
95
|
+
/** Available actions */
|
|
96
|
+
actions: IToolAction[];
|
|
97
|
+
/** Initialize the tool */
|
|
98
|
+
initialize(): Promise<void>;
|
|
99
|
+
/** Cleanup resources */
|
|
100
|
+
cleanup(): Promise<void>;
|
|
101
|
+
/** Execute an action */
|
|
102
|
+
execute(action: string, params: Record<string, unknown>): Promise<IToolExecutionResult>;
|
|
103
|
+
/** Get a summary for Guardian review */
|
|
104
|
+
getCallSummary(action: string, params: Record<string, unknown>): string;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// ================================
|
|
108
|
+
// Guardian Interfaces
|
|
109
|
+
// ================================
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Request for Guardian evaluation
|
|
113
|
+
*/
|
|
114
|
+
export interface IGuardianEvaluationRequest {
|
|
115
|
+
/** The proposed tool call */
|
|
116
|
+
proposal: IToolCallProposal;
|
|
117
|
+
/** Current task context */
|
|
118
|
+
taskContext: string;
|
|
119
|
+
/** Recent conversation history (last N messages) */
|
|
120
|
+
recentHistory: IAgentMessage[];
|
|
121
|
+
/** Summary of what the tool call will do */
|
|
122
|
+
callSummary: string;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Guardian's decision
|
|
127
|
+
*/
|
|
128
|
+
export interface IGuardianDecision {
|
|
129
|
+
/** Approve or reject */
|
|
130
|
+
decision: 'approve' | 'reject';
|
|
131
|
+
/** Explanation of the decision */
|
|
132
|
+
reason: string;
|
|
133
|
+
/** Specific concerns if rejected */
|
|
134
|
+
concerns?: string[];
|
|
135
|
+
/** Suggestions for the Driver if rejected */
|
|
136
|
+
suggestions?: string;
|
|
137
|
+
/** Confidence level (0-1) */
|
|
138
|
+
confidence?: number;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// ================================
|
|
142
|
+
// Result Interfaces
|
|
143
|
+
// ================================
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Log entry for tool executions
|
|
147
|
+
*/
|
|
148
|
+
export interface IToolExecutionLog {
|
|
149
|
+
timestamp: Date;
|
|
150
|
+
toolName: string;
|
|
151
|
+
action: string;
|
|
152
|
+
params: Record<string, unknown>;
|
|
153
|
+
guardianDecision: 'approved' | 'rejected';
|
|
154
|
+
guardianReason: string;
|
|
155
|
+
executionResult?: unknown;
|
|
156
|
+
executionError?: string;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Status of a dual-agent run
|
|
161
|
+
*/
|
|
162
|
+
export type TDualAgentRunStatus =
|
|
163
|
+
| 'completed'
|
|
164
|
+
| 'in_progress'
|
|
165
|
+
| 'max_iterations_reached'
|
|
166
|
+
| 'max_rejections_reached'
|
|
167
|
+
| 'clarification_needed'
|
|
168
|
+
| 'error';
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Result of a dual-agent run
|
|
172
|
+
*/
|
|
173
|
+
export interface IDualAgentRunResult {
|
|
174
|
+
/** Whether the task was successful */
|
|
175
|
+
success: boolean;
|
|
176
|
+
/** Whether the task is completed */
|
|
177
|
+
completed: boolean;
|
|
178
|
+
/** Final result or response */
|
|
179
|
+
result: string;
|
|
180
|
+
/** Total iterations taken */
|
|
181
|
+
iterations: number;
|
|
182
|
+
/** Full conversation history */
|
|
183
|
+
history: IAgentMessage[];
|
|
184
|
+
/** Current status */
|
|
185
|
+
status: TDualAgentRunStatus;
|
|
186
|
+
/** Number of tool calls made */
|
|
187
|
+
toolCallCount?: number;
|
|
188
|
+
/** Number of Guardian rejections */
|
|
189
|
+
rejectionCount?: number;
|
|
190
|
+
/** Tool execution log */
|
|
191
|
+
toolLog?: IToolExecutionLog[];
|
|
192
|
+
/** Error message if status is 'error' */
|
|
193
|
+
error?: string;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// ================================
|
|
197
|
+
// Utility Types
|
|
198
|
+
// ================================
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Available tool names
|
|
202
|
+
*/
|
|
203
|
+
export type TToolName = 'filesystem' | 'http' | 'browser' | 'shell';
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Generate a unique proposal ID
|
|
207
|
+
*/
|
|
208
|
+
export function generateProposalId(): string {
|
|
209
|
+
return `proposal_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
210
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import * as interfaces from './smartagent.interfaces.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Abstract base class for tool wrappers
|
|
5
|
+
* All tool implementations should extend this class
|
|
6
|
+
*/
|
|
7
|
+
export abstract class BaseToolWrapper implements interfaces.IAgentToolWrapper {
|
|
8
|
+
abstract name: string;
|
|
9
|
+
abstract description: string;
|
|
10
|
+
abstract actions: interfaces.IToolAction[];
|
|
11
|
+
|
|
12
|
+
protected isInitialized = false;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Initialize the tool and any required resources
|
|
16
|
+
*/
|
|
17
|
+
abstract initialize(): Promise<void>;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Cleanup any resources used by the tool
|
|
21
|
+
*/
|
|
22
|
+
abstract cleanup(): Promise<void>;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Execute an action with the given parameters
|
|
26
|
+
*/
|
|
27
|
+
abstract execute(
|
|
28
|
+
action: string,
|
|
29
|
+
params: Record<string, unknown>
|
|
30
|
+
): Promise<interfaces.IToolExecutionResult>;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Generate a human-readable summary of what the action will do
|
|
34
|
+
* This is used by the Guardian to understand the proposed action
|
|
35
|
+
*/
|
|
36
|
+
abstract getCallSummary(action: string, params: Record<string, unknown>): string;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Validate that an action exists for this tool
|
|
40
|
+
* @throws Error if the action is not valid
|
|
41
|
+
*/
|
|
42
|
+
protected validateAction(action: string): void {
|
|
43
|
+
const validAction = this.actions.find((a) => a.name === action);
|
|
44
|
+
if (!validAction) {
|
|
45
|
+
const availableActions = this.actions.map((a) => a.name).join(', ');
|
|
46
|
+
throw new Error(
|
|
47
|
+
`Unknown action "${action}" for tool "${this.name}". Available actions: ${availableActions}`
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Check if the tool is initialized
|
|
54
|
+
*/
|
|
55
|
+
protected ensureInitialized(): void {
|
|
56
|
+
if (!this.isInitialized) {
|
|
57
|
+
throw new Error(`Tool "${this.name}" is not initialized. Call initialize() first.`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Get the full tool description including all actions
|
|
63
|
+
* Used for Driver's tool awareness
|
|
64
|
+
*/
|
|
65
|
+
public getFullDescription(): string {
|
|
66
|
+
const actionDescriptions = this.actions
|
|
67
|
+
.map((a) => ` - ${a.name}: ${a.description}`)
|
|
68
|
+
.join('\n');
|
|
69
|
+
|
|
70
|
+
return `${this.name}: ${this.description}\nActions:\n${actionDescriptions}`;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Get the JSON schema for a specific action
|
|
75
|
+
*/
|
|
76
|
+
public getActionSchema(action: string): Record<string, unknown> | undefined {
|
|
77
|
+
const actionDef = this.actions.find((a) => a.name === action);
|
|
78
|
+
return actionDef?.parameters;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
import * as interfaces from './smartagent.interfaces.js';
|
|
3
|
+
import { BaseToolWrapper } from './smartagent.tools.base.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Browser tool for web page interaction
|
|
7
|
+
* Wraps @push.rocks/smartbrowser (Puppeteer-based)
|
|
8
|
+
*/
|
|
9
|
+
export class BrowserTool extends BaseToolWrapper {
|
|
10
|
+
public name = 'browser';
|
|
11
|
+
public description =
|
|
12
|
+
'Interact with web pages - take screenshots, generate PDFs, and execute JavaScript on pages';
|
|
13
|
+
|
|
14
|
+
public actions: interfaces.IToolAction[] = [
|
|
15
|
+
{
|
|
16
|
+
name: 'screenshot',
|
|
17
|
+
description: 'Take a screenshot of a webpage',
|
|
18
|
+
parameters: {
|
|
19
|
+
type: 'object',
|
|
20
|
+
properties: {
|
|
21
|
+
url: { type: 'string', description: 'URL of the page to screenshot' },
|
|
22
|
+
},
|
|
23
|
+
required: ['url'],
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: 'pdf',
|
|
28
|
+
description: 'Generate a PDF from a webpage',
|
|
29
|
+
parameters: {
|
|
30
|
+
type: 'object',
|
|
31
|
+
properties: {
|
|
32
|
+
url: { type: 'string', description: 'URL of the page to convert to PDF' },
|
|
33
|
+
},
|
|
34
|
+
required: ['url'],
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'evaluate',
|
|
39
|
+
description:
|
|
40
|
+
'Execute JavaScript code on a webpage and return the result. The script runs in the browser context.',
|
|
41
|
+
parameters: {
|
|
42
|
+
type: 'object',
|
|
43
|
+
properties: {
|
|
44
|
+
url: { type: 'string', description: 'URL of the page to run the script on' },
|
|
45
|
+
script: {
|
|
46
|
+
type: 'string',
|
|
47
|
+
description:
|
|
48
|
+
'JavaScript code to execute. Must be a valid expression or statements that return a value.',
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
required: ['url', 'script'],
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: 'getPageContent',
|
|
56
|
+
description: 'Get the text content and title of a webpage',
|
|
57
|
+
parameters: {
|
|
58
|
+
type: 'object',
|
|
59
|
+
properties: {
|
|
60
|
+
url: { type: 'string', description: 'URL of the page to get content from' },
|
|
61
|
+
},
|
|
62
|
+
required: ['url'],
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
private smartbrowser!: plugins.smartbrowser.SmartBrowser;
|
|
68
|
+
|
|
69
|
+
public async initialize(): Promise<void> {
|
|
70
|
+
this.smartbrowser = new plugins.smartbrowser.SmartBrowser();
|
|
71
|
+
await this.smartbrowser.start();
|
|
72
|
+
this.isInitialized = true;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
public async cleanup(): Promise<void> {
|
|
76
|
+
if (this.smartbrowser) {
|
|
77
|
+
await this.smartbrowser.stop();
|
|
78
|
+
}
|
|
79
|
+
this.isInitialized = false;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public async execute(
|
|
83
|
+
action: string,
|
|
84
|
+
params: Record<string, unknown>
|
|
85
|
+
): Promise<interfaces.IToolExecutionResult> {
|
|
86
|
+
this.validateAction(action);
|
|
87
|
+
this.ensureInitialized();
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
switch (action) {
|
|
91
|
+
case 'screenshot': {
|
|
92
|
+
const result = await this.smartbrowser.screenshotFromPage(params.url as string);
|
|
93
|
+
return {
|
|
94
|
+
success: true,
|
|
95
|
+
result: {
|
|
96
|
+
url: params.url,
|
|
97
|
+
name: result.name,
|
|
98
|
+
id: result.id,
|
|
99
|
+
bufferBase64: Buffer.from(result.buffer).toString('base64'),
|
|
100
|
+
bufferLength: result.buffer.length,
|
|
101
|
+
type: 'screenshot',
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
case 'pdf': {
|
|
107
|
+
const result = await this.smartbrowser.pdfFromPage(params.url as string);
|
|
108
|
+
return {
|
|
109
|
+
success: true,
|
|
110
|
+
result: {
|
|
111
|
+
url: params.url,
|
|
112
|
+
name: result.name,
|
|
113
|
+
id: result.id,
|
|
114
|
+
bufferBase64: Buffer.from(result.buffer).toString('base64'),
|
|
115
|
+
bufferLength: result.buffer.length,
|
|
116
|
+
type: 'pdf',
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
case 'evaluate': {
|
|
122
|
+
const script = params.script as string;
|
|
123
|
+
// Create an async function from the script
|
|
124
|
+
// The script should be valid JavaScript that returns a value
|
|
125
|
+
const result = await this.smartbrowser.evaluateOnPage(params.url as string, async () => {
|
|
126
|
+
// This runs in the browser context
|
|
127
|
+
// We need to evaluate the script string dynamically
|
|
128
|
+
// eslint-disable-next-line no-eval
|
|
129
|
+
return eval(script);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
success: true,
|
|
134
|
+
result: {
|
|
135
|
+
url: params.url,
|
|
136
|
+
script: script.substring(0, 200) + (script.length > 200 ? '...' : ''),
|
|
137
|
+
evaluationResult: result,
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
case 'getPageContent': {
|
|
143
|
+
const result = await this.smartbrowser.evaluateOnPage(params.url as string, async () => {
|
|
144
|
+
return {
|
|
145
|
+
title: document.title,
|
|
146
|
+
textContent: document.body?.innerText || '',
|
|
147
|
+
url: window.location.href,
|
|
148
|
+
};
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
success: true,
|
|
153
|
+
result: {
|
|
154
|
+
url: params.url,
|
|
155
|
+
title: result.title,
|
|
156
|
+
textContent:
|
|
157
|
+
result.textContent.length > 10000
|
|
158
|
+
? result.textContent.substring(0, 10000) + '... [truncated]'
|
|
159
|
+
: result.textContent,
|
|
160
|
+
actualUrl: result.url,
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
default:
|
|
166
|
+
return {
|
|
167
|
+
success: false,
|
|
168
|
+
error: `Unknown action: ${action}`,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
} catch (error) {
|
|
172
|
+
return {
|
|
173
|
+
success: false,
|
|
174
|
+
error: error instanceof Error ? error.message : String(error),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
public getCallSummary(action: string, params: Record<string, unknown>): string {
|
|
180
|
+
switch (action) {
|
|
181
|
+
case 'screenshot':
|
|
182
|
+
return `Take screenshot of "${params.url}"`;
|
|
183
|
+
|
|
184
|
+
case 'pdf':
|
|
185
|
+
return `Generate PDF from "${params.url}"`;
|
|
186
|
+
|
|
187
|
+
case 'evaluate': {
|
|
188
|
+
const script = params.script as string;
|
|
189
|
+
const preview = script.length > 100 ? script.substring(0, 100) + '...' : script;
|
|
190
|
+
return `Execute JavaScript on "${params.url}": "${preview}"`;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
case 'getPageContent':
|
|
194
|
+
return `Get text content and title from "${params.url}"`;
|
|
195
|
+
|
|
196
|
+
default:
|
|
197
|
+
return `Unknown action: ${action}`;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|