Files
xiaoli-cli/plugins/operit/extended_http_tools.ts
T
xiaoli-cli bot dfe21298b9 release: v5.4.2 - terminal模拟器 + Operit桥接
新增插件:
- terminal: 持久交互式终端,纯标准库,全平台,13个测试
- operit_bridge: Operit AI工具格式桥接,47个脚本288个工具,12个测试

其他:
- plugins/operit/: 47个Operit官方脚本
- 更新plugin_registry.json/plugins_config.py
- 更新about.txt/CHANGELOG.md至v5.4.2
2026-06-23 08:50:15 +00:00

210 lines
9.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* METADATA
{
"name": "extended_http_tools",
"display_name": {
"zh": "增强 HTTP 工具",
"en": "Extended HTTP Tools"
},
"description": {
"zh": "允许文件上传,以及 GET/POST 等网络直接访问操作。",
"en": "Allows file uploads and direct network access operations such as GET/POST."
},
"enabledByDefault": true,
"category": "Network",
"tools": [
{
"name": "http_request",
"description": { "zh": "发送 HTTP 请求。", "en": "Send an HTTP request." },
"parameters": [
{ "name": "url", "description": { "zh": "请求 URL", "en": "Request URL" }, "type": "string", "required": true },
{ "name": "method", "description": { "zh": "请求方法:GET/POST/PUT/DELETE", "en": "Method: GET/POST/PUT/DELETE" }, "type": "string", "required": true },
{ "name": "headers", "description": { "zh": "可选:headers(JSON 对象字符串)", "en": "Optional: headers (JSON object string)" }, "type": "string", "required": false },
{ "name": "body", "description": { "zh": "可选:请求体(字符串)", "en": "Optional: body (string)" }, "type": "string", "required": false },
{ "name": "body_type", "description": { "zh": "可选:json/form/text/xml", "en": "Optional: json/form/text/xml" }, "type": "string", "required": false },
{ "name": "ignore_ssl", "description": { "zh": "可选:是否忽略 HTTPS 证书校验(true/false)", "en": "Optional: ignore HTTPS certificate verification (true/false)" }, "type": "boolean", "required": false }
]
},
{
"name": "multipart_request",
"description": { "zh": "上传文件(multipart)。", "en": "Upload files (multipart)." },
"parameters": [
{ "name": "url", "description": { "zh": "请求 URL", "en": "Request URL" }, "type": "string", "required": true },
{ "name": "method", "description": { "zh": "请求方法:POST/PUT", "en": "Method: POST/PUT" }, "type": "string", "required": true },
{ "name": "headers", "description": { "zh": "可选:headers(JSON 对象字符串)", "en": "Optional: headers (JSON object string)" }, "type": "string", "required": false },
{ "name": "form_data", "description": { "zh": "可选:form_data(字符串)", "en": "Optional: form_data (string)" }, "type": "string", "required": false },
{ "name": "files", "description": { "zh": "可选:files(JSON 数组字符串)", "en": "Optional: files (JSON array string)" }, "type": "string", "required": false },
{ "name": "ignore_ssl", "description": { "zh": "可选:是否忽略 HTTPS 证书校验(true/false)", "en": "Optional: ignore HTTPS certificate verification (true/false)" }, "type": "boolean", "required": false }
]
},
{
"name": "manage_cookies",
"description": { "zh": "管理 Cookies。", "en": "Manage cookies." },
"parameters": [
{ "name": "action", "description": { "zh": "操作:get/set/clear", "en": "Action: get/set/clear" }, "type": "string", "required": true },
{ "name": "domain", "description": { "zh": "可选:域名", "en": "Optional: domain" }, "type": "string", "required": false },
{ "name": "cookies", "description": { "zh": "可选:cookies(字符串)", "en": "Optional: cookies (string)" }, "type": "string", "required": false }
]
}
]
}*/
const ExtendedHttpTools = (function () {
const MAX_INLINE_HTTP_RESPONSE_CHARS = 12_000;
interface ToolResponse {
success: boolean;
message: string;
data?: any;
}
async function http_request(params: {
url: string;
method: string;
headers?: string;
body?: string;
body_type?: string;
ignore_ssl?: boolean;
}): Promise<ToolResponse> {
const toolParams: ToolParams = {
url: params.url,
method: params.method,
};
if (params.headers !== undefined) toolParams.headers = params.headers;
if (params.body !== undefined) toolParams.body = params.body;
if (params.body_type !== undefined) toolParams.body_type = params.body_type;
if (params.ignore_ssl !== undefined) toolParams.ignore_ssl = params.ignore_ssl;
const result = await toolCall({ name: "http_request", params: toolParams });
const success = result.statusCode >= 200 && result.statusCode < 400;
const contentStr = typeof result?.content === "string" ? result.content : "";
if (contentStr.length > MAX_INLINE_HTTP_RESPONSE_CHARS) {
await Tools.Files.mkdir(OPERIT_CLEAN_ON_EXIT_DIR, true);
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
const rand = Math.floor(Math.random() * 1_000_000);
let ext = "txt";
const ct = typeof result?.contentType === "string" ? result.contentType.toLowerCase() : "";
if (ct.includes("json")) ext = "json";
else if (ct.includes("html")) ext = "html";
else if (ct.includes("xml")) ext = "xml";
const filePath = `${OPERIT_CLEAN_ON_EXIT_DIR}/http_response_${timestamp}_${rand}.${ext}`;
await Tools.Files.write(filePath, contentStr, false);
const resultMeta = {
url: result?.url,
statusCode: result?.statusCode,
statusMessage: result?.statusMessage,
headers: result?.headers,
contentType: result?.contentType,
size: result?.size,
content: "(saved_to_file)",
};
return {
success,
message: `HTTP 请求完成;响应内容过大,已保存到文件:${filePath}。请使用 read_file_part 读取指定行范围,或用 grep_code 在该文件中检索关键字。`,
data: {
result: resultMeta,
content_saved_to: filePath,
operit_clean_on_exit_dir: OPERIT_CLEAN_ON_EXIT_DIR,
},
};
}
return { success, message: 'HTTP 请求完成', data: result };
}
async function multipart_request(params: {
url: string;
method: string;
headers?: string;
form_data?: string;
files?: string;
ignore_ssl?: boolean;
}): Promise<ToolResponse> {
const toolParams: ToolParams = {
url: params.url,
method: params.method,
};
if (params.headers !== undefined) toolParams.headers = params.headers;
if (params.form_data !== undefined) toolParams.form_data = params.form_data;
if (params.files !== undefined) toolParams.files = params.files;
if (params.ignore_ssl !== undefined) toolParams.ignore_ssl = params.ignore_ssl;
const result = await toolCall({ name: "multipart_request", params: toolParams });
const success = result.statusCode >= 200 && result.statusCode < 400;
return { success, message: '文件上传完成', data: result };
}
async function manage_cookies(params: { action: string; domain?: string; cookies?: string }): Promise<ToolResponse> {
const toolParams: ToolParams = {
action: params.action,
};
if (params.domain !== undefined) toolParams.domain = params.domain;
if (params.cookies !== undefined) toolParams.cookies = params.cookies;
const result = await toolCall({ name: "manage_cookies", params: toolParams });
const success = result.statusCode >= 200 && result.statusCode < 400;
return { success, message: 'Cookies 操作完成', data: result };
}
async function wrapToolExecution<P>(func: (params: P) => Promise<ToolResponse>, params: P) {
try {
const result = await func(params);
complete(result);
} catch (error: any) {
console.error(`Tool ${func.name} failed unexpectedly`, error);
complete({
success: false,
message: `工具执行时发生意外错误: ${error.message}`,
});
}
}
async function main() {
const results: any[] = [];
// 这些工具可能对外发请求 / 写 cookies,默认不做自动化演示。
results.push({ tool: 'http_request', result: { success: null, message: '未测试(会对外发起网络请求)' } });
results.push({ tool: 'multipart_request', result: { success: null, message: '未测试(会上传文件/对外发起网络请求)' } });
results.push({ tool: 'manage_cookies', result: { success: null, message: '未测试(会读写 cookies)' } });
complete({
success: true,
message: "拓展 HTTP 工具包加载完成(未执行网络请求测试)",
data: { results }
});
}
return {
http_request: (params: {
url: string;
method: string;
headers?: string;
body?: string;
body_type?: string;
ignore_ssl?: boolean;
}) => wrapToolExecution(http_request, params),
multipart_request: (params: {
url: string;
method: string;
headers?: string;
form_data?: string;
files?: string;
ignore_ssl?: boolean;
}) => wrapToolExecution(multipart_request, params),
manage_cookies: (params: { action: string; domain?: string; cookies?: string }) => wrapToolExecution(manage_cookies, params),
main,
};
})();
exports.http_request = ExtendedHttpTools.http_request;
exports.multipart_request = ExtendedHttpTools.multipart_request;
exports.manage_cookies = ExtendedHttpTools.manage_cookies;
exports.main = ExtendedHttpTools.main;