| 43 | }, |
| 44 | required: ['url'], |
| 45 | async execute(params) { |
| 46 | const { url, method, headers, body, timeout, followRedirects } = params; |
| 47 | |
| 48 | try { |
| 49 | // 动态导入 axios |
| 50 | const axios = (await import('axios')).default; |
| 51 | |
| 52 | const config: any = { |
| 53 | url, |
| 54 | method: method.toLowerCase(), |
| 55 | headers: { |
| 56 | 'User-Agent': 'Agent-CLI/1.0.0', |
| 57 | ...headers, |
| 58 | }, |
| 59 | timeout, |
| 60 | validateStatus: () => true, // 接受所有状态码 |
| 61 | maxRedirects: followRedirects ? 5 : 0, |
| 62 | }; |
| 63 | |
| 64 | if (body && ['post', 'put', 'patch'].includes(method.toLowerCase())) { |
| 65 | config.data = body; |
| 66 | |
| 67 | // 如果没有指定 Content-Type,尝试自动检测 |
| 68 | if (!headers['Content-Type'] && !headers['content-type']) { |
| 69 | try { |
| 70 | JSON.parse(body); |
| 71 | config.headers['Content-Type'] = 'application/json'; |
| 72 | } catch { |
| 73 | config.headers['Content-Type'] = 'text/plain'; |
| 74 | } |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | const startTime = Date.now(); |
| 79 | const response = await axios(config); |
| 80 | const duration = Date.now() - startTime; |
| 81 | |
| 82 | return { |
| 83 | success: true, |
| 84 | data: { |
| 85 | status: response.status, |
| 86 | statusText: response.statusText, |
| 87 | headers: response.headers, |
| 88 | data: response.data, |
| 89 | duration, |
| 90 | url: response.config.url, |
| 91 | method: response.config.method?.toUpperCase(), |
| 92 | }, |
| 93 | metadata: { |
| 94 | requestConfig: { |
| 95 | url, |
| 96 | method, |
| 97 | headers: config.headers, |
| 98 | timeout, |
| 99 | }, |
| 100 | }, |
| 101 | }; |
| 102 | } catch (error: any) { |