新增: http_request AI工具(结构化HTTP·SSRF防御·High审批)

- 后端: Cargo.toml reqwest0.12(json/gzip/brotli native-tls对齐df-ai) + http.rs(handler+SSRF三层防御 validate_url/resolve_and_check/重定向≤3跳每跳校验) + tool_registry register_http_tools + 基线28→29
- 前端: useToolCard formatHttpResult + ToolCard渲染(method/url/status/body折叠/截断) + HIGH_RISK_TOOLS + confirmHighHttp + i18n
- SSRF: localhost/私有IP(127/10/172.16/192.168/169.254云元数据/100.64CGNAT/≥224/IPv6保留)拒绝 + DNS resolve校验防重绑定 + 重定向每跳重校验
- 审批: High(统一保守 GET也审批 防漏写操作)
- 截断: 响应50KB(T-05)+ 请求1MB + 超时1-60s默认30
This commit is contained in:
2026-06-19 12:48:28 +08:00
parent b42cc66e7a
commit f1a06732fd
8 changed files with 904 additions and 5 deletions

View File

@@ -82,6 +82,11 @@ export default {
renamedCrossVolume: 'Moved {from} → {to} (cross-volume, {bytes})',
writeOverwrite: 'overwrote {old} → {neww}',
encodingLabel: 'encoding: {enc}',
// http_request result summary (method + status + elapsed; body in expanded view)
httpOk: '{method} {status} OK ({ms} ms)',
httpFailed: '{method} {status} failed',
httpTruncated: 'Response truncated ({bytes}), see details',
httpRequestFallback: 'HTTP Request',
foundN: 'Found {n}',
boundDir: 'Bound directory "{path}" stack: {stack}',
deleteFilePermanent: 'Permanently deleted {path}',
@@ -125,6 +130,7 @@ export default {
purgeProject: 'Purge Project',
updateProject: 'Update Project',
runWorkflow: 'Run Workflow',
httpRequest: 'HTTP Request',
},
// UX-260617-14: approval loading fallback timeout notice (no backend ack, card still pending_approval → reset + prompt)
@@ -133,6 +139,9 @@ export default {
// UX-260617-18: tool failure detection copy (regex narrowed to line-anchored err_msg prefix)
// (reuse executionFailed/executionFailedHint, no new key)
// http_request High-risk confirm: external network call, data may leak via URL/body
confirmHighHttp: 'Send this HTTP request to an external server?',
// Approval argument key labels
argLabel: {
id: 'ID',
@@ -146,6 +155,12 @@ export default {
priority: 'Priority',
tags: 'Tags',
source: 'Source',
method: 'Method',
url: 'URL',
body: 'Body',
headers: 'Headers',
timeout_secs: 'Timeout (s)',
parse: 'Parse',
},
},
}