- dialogService 接收并传递 mode 参数 - apiClient 构造带 mode 的请求 - messageHandler 从 WebView 消息获取 mode
167 lines
3.9 KiB
TypeScript
167 lines
3.9 KiB
TypeScript
/**
|
||
* API 客户端
|
||
* 封装与后端的 HTTP 通信
|
||
*/
|
||
import * as https from 'https';
|
||
import * as http from 'http';
|
||
import { URL } from 'url';
|
||
import { getApiUrl, getConfig } from '../config/settings';
|
||
import type { ToolCallResult, AnswerRequest, ToolResultResponse, AnswerResponse, ToolConfirmResponse } from '../types/api';
|
||
|
||
/**
|
||
* HTTP 请求选项
|
||
*/
|
||
interface RequestOptions {
|
||
method: 'GET' | 'POST' | 'PUT' | 'DELETE';
|
||
headers?: Record<string, string>;
|
||
body?: unknown;
|
||
timeout?: number;
|
||
}
|
||
|
||
/**
|
||
* 发送 HTTP 请求
|
||
*/
|
||
async function request<T>(path: string, options: RequestOptions): Promise<T> {
|
||
const url = new URL(getApiUrl(path));
|
||
const { timeout } = getConfig();
|
||
|
||
const isHttps = url.protocol === 'https:';
|
||
const httpModule = isHttps ? https : http;
|
||
|
||
const requestOptions: http.RequestOptions = {
|
||
hostname: url.hostname,
|
||
port: url.port || (isHttps ? 443 : 80),
|
||
path: url.pathname + url.search,
|
||
method: options.method,
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
...options.headers
|
||
},
|
||
timeout: options.timeout || timeout
|
||
};
|
||
|
||
return new Promise((resolve, reject) => {
|
||
const req = httpModule.request(requestOptions, (res) => {
|
||
let data = '';
|
||
|
||
res.on('data', (chunk) => {
|
||
data += chunk;
|
||
});
|
||
|
||
res.on('end', () => {
|
||
try {
|
||
const json = JSON.parse(data);
|
||
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
|
||
resolve(json as T);
|
||
} else {
|
||
reject(new Error(json.error || json.message || `HTTP ${res.statusCode}`));
|
||
}
|
||
} catch (e) {
|
||
reject(new Error(`解析响应失败: ${data}`));
|
||
}
|
||
});
|
||
});
|
||
|
||
req.on('error', (error) => {
|
||
reject(error);
|
||
});
|
||
|
||
req.on('timeout', () => {
|
||
req.destroy();
|
||
reject(new Error('请求超时'));
|
||
});
|
||
|
||
if (options.body) {
|
||
req.write(JSON.stringify(options.body));
|
||
}
|
||
|
||
req.end();
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 提交工具执行结果
|
||
* POST /api/tool/result
|
||
*/
|
||
export async function submitToolResult(result: ToolCallResult): Promise<ToolResultResponse> {
|
||
console.log(`[API] 提交工具结果: callId=${result.id}`);
|
||
return request<ToolResultResponse>('/api/tool/result', {
|
||
method: 'POST',
|
||
body: result
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 提交用户回答
|
||
* POST /api/task/answer
|
||
*/
|
||
export async function submitAnswer(answer: AnswerRequest): Promise<AnswerResponse> {
|
||
console.log(`[API] 提交用户回答: askId=${answer.askId}`);
|
||
return request<AnswerResponse>('/api/task/answer', {
|
||
method: 'POST',
|
||
body: answer
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 提交工具确认响应(Ask 模式)
|
||
* POST /api/tool/confirm
|
||
*/
|
||
export async function submitToolConfirm(response: ToolConfirmResponse): Promise<ToolResultResponse> {
|
||
console.log(`[API] 提交工具确认: confirmId=${response.confirmId}, approved=${response.approved}`);
|
||
return request<ToolResultResponse>('/api/tool/confirm', {
|
||
method: 'POST',
|
||
body: response
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 健康检查
|
||
* GET /api/dialog/health
|
||
*/
|
||
export async function healthCheck(): Promise<{ status: string }> {
|
||
return request<{ status: string }>('/api/dialog/health', {
|
||
method: 'GET',
|
||
timeout: 5000
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 创建成功的工具结果
|
||
*/
|
||
export function createSuccessResult(id: number, text: string): ToolCallResult {
|
||
return {
|
||
jsonrpc: '2.0',
|
||
id,
|
||
result: {
|
||
content: [{ type: 'text', text }],
|
||
isError: false
|
||
}
|
||
};
|
||
}
|
||
|
||
/**
|
||
* 创建业务错误的工具结果(如编译失败)
|
||
*/
|
||
export function createBusinessErrorResult(id: number, errorMessage: string): ToolCallResult {
|
||
return {
|
||
jsonrpc: '2.0',
|
||
id,
|
||
result: {
|
||
content: [{ type: 'text', text: errorMessage }],
|
||
isError: true
|
||
}
|
||
};
|
||
}
|
||
|
||
/**
|
||
* 创建系统错误的工具结果
|
||
*/
|
||
export function createSystemErrorResult(id: number, code: number, message: string): ToolCallResult {
|
||
return {
|
||
jsonrpc: '2.0',
|
||
id,
|
||
error: { code, message }
|
||
};
|
||
}
|