update pay function

This commit is contained in:
2025-11-22 08:57:37 +08:00
parent 990ca3663e
commit e778742590
210 changed files with 8236 additions and 5345 deletions

View File

@@ -0,0 +1,277 @@
// services/mcp-real.ts - 对接真实的 MCP 服务器接口
import { checkAuth } from '../lib/auth';
// ========== 类型定义 ==========
export interface ChatMessage {
role: 'user' | 'assistant' | 'system';
content: string;
timestamp?: string;
}
export interface Tool {
name: string;
description: string;
input_schema: {
type: string;
properties: Record<string, any>;
required?: string[];
};
}
export interface ToolCallRequest {
tool: string;
arguments: Record<string, any>;
}
export interface ToolCallResponse {
tool: string;
result: any;
error?: string;
execution_time?: number;
}
// ========== MCP 服务类 ==========
export class MCPService {
// 使用相对路径,通过 Nginx 代理访问
private baseUrl = '/mcp';
private chatHistory: ChatMessage[] = [];
/**
* 获取可用工具列表
*/
async getTools(): Promise<Tool[]> {
try {
const response = await fetch(`${this.baseUrl}/tools`, {
method: 'GET',
credentials: 'include',
});
if (!response.ok) {
throw new Error(`Failed to get tools: ${response.statusText}`);
}
const data = await response.json();
return data.tools || [];
} catch (error) {
console.error('Failed to get tools:', error);
return [];
}
}
/**
* 调用特定工具
*/
async callTool(toolName: string, args: Record<string, any>): Promise<ToolCallResponse> {
try {
const response = await fetch(`${this.baseUrl}/tools/call`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
credentials: 'include',
body: JSON.stringify({
tool: toolName,
arguments: args,
}),
});
if (!response.ok) {
const error = await response.text();
throw new Error(`Tool call failed: ${error}`);
}
return await response.json();
} catch (error) {
console.error('Tool call error:', error);
throw error;
}
}
/**
* 发送聊天消息(非流式)
*/
async sendMessage(message: string): Promise<string> {
// 添加用户消息到历史
this.chatHistory.push({
role: 'user',
content: message,
timestamp: new Date().toISOString(),
});
try {
const response = await fetch(`${this.baseUrl}/chat`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
credentials: 'include',
body: JSON.stringify({
messages: this.chatHistory,
stream: false,
}),
});
if (!response.ok) {
throw new Error(`Chat failed: ${response.statusText}`);
}
const data = await response.json();
// 添加助手回复到历史
if (data.response) {
this.chatHistory.push({
role: 'assistant',
content: data.response,
timestamp: new Date().toISOString(),
});
}
return data.response || data.message || '抱歉,没有收到有效的回复';
} catch (error) {
console.error('Send message error:', error);
throw error;
}
}
/**
* 发送聊天消息(流式响应)
*/
async *streamMessage(message: string): AsyncGenerator<string, void, unknown> {
// 添加用户消息到历史
this.chatHistory.push({
role: 'user',
content: message,
timestamp: new Date().toISOString(),
});
try {
const response = await fetch(`${this.baseUrl}/chat`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
credentials: 'include',
body: JSON.stringify({
messages: this.chatHistory,
stream: true,
}),
});
if (!response.ok) {
throw new Error(`Stream failed: ${response.statusText}`);
}
// 处理 SSE 流
const reader = response.body?.getReader();
const decoder = new TextDecoder();
if (!reader) {
throw new Error('No response body');
}
let buffer = '';
let fullResponse = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split('\n');
// 保留最后一行(可能不完整)
buffer = lines.pop() || '';
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = line.slice(6).trim();
if (data === '[DONE]') {
// 流结束,保存完整回复到历史
if (fullResponse) {
this.chatHistory.push({
role: 'assistant',
content: fullResponse,
timestamp: new Date().toISOString(),
});
}
return;
}
try {
const parsed = JSON.parse(data);
const content = parsed.content || parsed.delta?.content || '';
fullResponse += content;
yield content;
} catch (e) {
// 如果不是 JSON直接输出
fullResponse += data;
yield data;
}
}
}
}
} catch (error) {
console.error('Stream message error:', error);
throw error;
}
}
/**
* 清空聊天历史
*/
clearHistory() {
this.chatHistory = [];
}
/**
* 获取聊天历史
*/
getHistory(): ChatMessage[] {
return this.chatHistory;
}
/**
* 执行代码(通过 code_interpreter 工具)
*/
async executeCode(code: string, language: string = 'python'): Promise<any> {
return this.callTool('code_interpreter', {
code,
language,
});
}
/**
* 文件操作工具封装
*/
async readFile(path: string): Promise<string> {
const result = await this.callTool('read_file', { path });
return result.result?.content || '';
}
async writeFile(path: string, content: string): Promise<void> {
await this.callTool('write_file', { path, content });
}
async listDirectory(path: string = '.'): Promise<string[]> {
const result = await this.callTool('list_directory', { path });
return result.result?.files || [];
}
/**
* 搜索工具封装
*/
async search(query: string): Promise<any> {
return this.callTool('search', { query });
}
/**
* 创建文件工具
*/
async createFile(path: string, content: string): Promise<void> {
await this.callTool('create_file', { path, content });
}
}
// 导出单例
export const mcpService = new MCPService();

View File

@@ -0,0 +1,138 @@
// services/mcp.ts - MCP API 调用服务
import { callMCPApi } from '../lib/auth';
export interface ChatMessage {
role: 'user' | 'assistant' | 'system';
content: string;
timestamp?: string;
tools?: any[];
}
export interface ChatSession {
id: string;
messages: ChatMessage[];
createdAt: string;
updatedAt: string;
}
export class MCPService {
/**
* 发送聊天消息到 MCP
*/
async sendMessage(message: string, sessionId?: string): Promise<any> {
const response = await callMCPApi('/api/mcp/chat', {
method: 'POST',
body: JSON.stringify({
message,
sessionId: sessionId || this.generateSessionId(),
model: 'claude-3-opus', // 或其他模型
}),
});
return response.json();
}
/**
* 流式发送消息SSE
*/
async *streamMessage(message: string, sessionId?: string) {
const response = await callMCPApi('/api/mcp/chat/stream', {
method: 'POST',
body: JSON.stringify({
message,
sessionId: sessionId || this.generateSessionId(),
stream: true,
}),
});
if (!response.ok) {
throw new Error('Stream request failed');
}
const reader = response.body?.getReader();
const decoder = new TextDecoder();
if (!reader) {
throw new Error('No response body');
}
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
const lines = chunk.split('\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = line.slice(6);
if (data === '[DONE]') {
return;
}
try {
yield JSON.parse(data);
} catch (e) {
console.error('Failed to parse SSE data:', e);
}
}
}
}
}
/**
* 获取可用的 MCP 工具列表
*/
async getAvailableTools(): Promise<any[]> {
const response = await callMCPApi('/api/mcp/tools');
return response.json();
}
/**
* 执行代码
*/
async executeCode(code: string, language: string = 'python'): Promise<any> {
const response = await callMCPApi('/api/mcp/execute', {
method: 'POST',
body: JSON.stringify({
code,
language,
}),
});
return response.json();
}
/**
* 生成代码
*/
async generateCode(prompt: string, language: string = 'python'): Promise<any> {
const response = await callMCPApi('/api/mcp/generate-code', {
method: 'POST',
body: JSON.stringify({
prompt,
language,
}),
});
return response.json();
}
/**
* 获取聊天历史
*/
async getChatHistory(sessionId?: string): Promise<ChatMessage[]> {
const params = sessionId ? `?sessionId=${sessionId}` : '';
const response = await callMCPApi(`/api/mcp/history${params}`);
return response.json();
}
/**
* 生成会话 ID
*/
private generateSessionId(): string {
return `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
}
// 导出单例
export const mcpService = new MCPService();