initial
This commit is contained in:
205
ts/smartagent.tools.http.ts
Normal file
205
ts/smartagent.tools.http.ts
Normal file
@@ -0,0 +1,205 @@
|
||||
import * as plugins from './plugins.js';
|
||||
import * as interfaces from './smartagent.interfaces.js';
|
||||
import { BaseToolWrapper } from './smartagent.tools.base.js';
|
||||
|
||||
/**
|
||||
* HTTP tool for making web requests
|
||||
* Wraps @push.rocks/smartrequest
|
||||
*/
|
||||
export class HttpTool extends BaseToolWrapper {
|
||||
public name = 'http';
|
||||
public description = 'Make HTTP requests to web APIs and services';
|
||||
|
||||
public actions: interfaces.IToolAction[] = [
|
||||
{
|
||||
name: 'get',
|
||||
description: 'Make a GET request',
|
||||
parameters: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
url: { type: 'string', description: 'URL to request' },
|
||||
headers: { type: 'object', description: 'Request headers (key-value pairs)' },
|
||||
query: { type: 'object', description: 'Query parameters (key-value pairs)' },
|
||||
timeout: { type: 'number', description: 'Timeout in milliseconds' },
|
||||
},
|
||||
required: ['url'],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'post',
|
||||
description: 'Make a POST request with JSON body',
|
||||
parameters: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
url: { type: 'string', description: 'URL to request' },
|
||||
body: { type: 'object', description: 'JSON body to send' },
|
||||
headers: { type: 'object', description: 'Request headers (key-value pairs)' },
|
||||
query: { type: 'object', description: 'Query parameters (key-value pairs)' },
|
||||
timeout: { type: 'number', description: 'Timeout in milliseconds' },
|
||||
},
|
||||
required: ['url'],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'put',
|
||||
description: 'Make a PUT request with JSON body',
|
||||
parameters: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
url: { type: 'string', description: 'URL to request' },
|
||||
body: { type: 'object', description: 'JSON body to send' },
|
||||
headers: { type: 'object', description: 'Request headers (key-value pairs)' },
|
||||
timeout: { type: 'number', description: 'Timeout in milliseconds' },
|
||||
},
|
||||
required: ['url', 'body'],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'patch',
|
||||
description: 'Make a PATCH request with JSON body',
|
||||
parameters: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
url: { type: 'string', description: 'URL to request' },
|
||||
body: { type: 'object', description: 'JSON body to send' },
|
||||
headers: { type: 'object', description: 'Request headers (key-value pairs)' },
|
||||
timeout: { type: 'number', description: 'Timeout in milliseconds' },
|
||||
},
|
||||
required: ['url', 'body'],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'delete',
|
||||
description: 'Make a DELETE request',
|
||||
parameters: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
url: { type: 'string', description: 'URL to request' },
|
||||
headers: { type: 'object', description: 'Request headers (key-value pairs)' },
|
||||
timeout: { type: 'number', description: 'Timeout in milliseconds' },
|
||||
},
|
||||
required: ['url'],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
public async initialize(): Promise<void> {
|
||||
// SmartRequest is stateless, no initialization needed
|
||||
this.isInitialized = true;
|
||||
}
|
||||
|
||||
public async cleanup(): Promise<void> {
|
||||
this.isInitialized = false;
|
||||
}
|
||||
|
||||
public async execute(
|
||||
action: string,
|
||||
params: Record<string, unknown>
|
||||
): Promise<interfaces.IToolExecutionResult> {
|
||||
this.validateAction(action);
|
||||
this.ensureInitialized();
|
||||
|
||||
try {
|
||||
let request = plugins.smartrequest.SmartRequest.create().url(params.url as string);
|
||||
|
||||
// Add headers
|
||||
if (params.headers && typeof params.headers === 'object') {
|
||||
for (const [key, value] of Object.entries(params.headers as Record<string, string>)) {
|
||||
request = request.header(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
// Add query parameters
|
||||
if (params.query && typeof params.query === 'object') {
|
||||
request = request.query(params.query as Record<string, string>);
|
||||
}
|
||||
|
||||
// Add timeout
|
||||
if (params.timeout) {
|
||||
request = request.timeout(params.timeout as number);
|
||||
}
|
||||
|
||||
// Add JSON body for POST, PUT, PATCH
|
||||
if (params.body && ['post', 'put', 'patch'].includes(action)) {
|
||||
request = request.json(params.body);
|
||||
}
|
||||
|
||||
// Execute the request
|
||||
let response;
|
||||
switch (action) {
|
||||
case 'get':
|
||||
response = await request.get();
|
||||
break;
|
||||
case 'post':
|
||||
response = await request.post();
|
||||
break;
|
||||
case 'put':
|
||||
response = await request.put();
|
||||
break;
|
||||
case 'patch':
|
||||
response = await request.patch();
|
||||
break;
|
||||
case 'delete':
|
||||
response = await request.delete();
|
||||
break;
|
||||
default:
|
||||
return { success: false, error: `Unknown action: ${action}` };
|
||||
}
|
||||
|
||||
// Parse response body
|
||||
let body: unknown;
|
||||
const contentType = response.headers?.['content-type'] || '';
|
||||
|
||||
try {
|
||||
if (contentType.includes('application/json')) {
|
||||
body = await response.json();
|
||||
} else {
|
||||
body = await response.text();
|
||||
}
|
||||
} catch {
|
||||
body = null;
|
||||
}
|
||||
|
||||
return {
|
||||
success: response.ok,
|
||||
result: {
|
||||
url: params.url,
|
||||
method: action.toUpperCase(),
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
ok: response.ok,
|
||||
headers: response.headers,
|
||||
body,
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public getCallSummary(action: string, params: Record<string, unknown>): string {
|
||||
const method = action.toUpperCase();
|
||||
let summary = `${method} request to "${params.url}"`;
|
||||
|
||||
if (params.query && Object.keys(params.query as object).length > 0) {
|
||||
const queryStr = JSON.stringify(params.query);
|
||||
summary += ` with query: ${queryStr.length > 50 ? queryStr.substring(0, 50) + '...' : queryStr}`;
|
||||
}
|
||||
|
||||
if (params.body) {
|
||||
const bodyStr = JSON.stringify(params.body);
|
||||
const preview = bodyStr.length > 100 ? bodyStr.substring(0, 100) + '...' : bodyStr;
|
||||
summary += ` with body: ${preview}`;
|
||||
}
|
||||
|
||||
if (params.headers && Object.keys(params.headers as object).length > 0) {
|
||||
const headerKeys = Object.keys(params.headers as object).join(', ');
|
||||
summary += ` with headers: [${headerKeys}]`;
|
||||
}
|
||||
|
||||
return summary;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user