update
This commit is contained in:
parent
e20bbf2b42
commit
295c45fa00
@ -24,11 +24,9 @@ export class MessageBridge {
|
|||||||
private handlers = new Map<string, Set<CommandHandler>>();
|
private handlers = new Map<string, Set<CommandHandler>>();
|
||||||
private isConnected: Promise<boolean> | null = null;
|
private isConnected: Promise<boolean> | null = null;
|
||||||
|
|
||||||
constructor(private wsUrl: string = 'ws://localhost:8080') {
|
constructor(
|
||||||
|
private setupSignature: any
|
||||||
// 环境检测优先级:
|
) {
|
||||||
// 1. VS Code WebView 环境
|
|
||||||
// 2. 浏览器 WebSocket 环境
|
|
||||||
|
|
||||||
const platform = getPlatform();
|
const platform = getPlatform();
|
||||||
|
|
||||||
@ -68,7 +66,14 @@ export class MessageBridge {
|
|||||||
|
|
||||||
// WebSocket 环境连接
|
// WebSocket 环境连接
|
||||||
private setupWebSocket() {
|
private setupWebSocket() {
|
||||||
this.ws = new WebSocket(this.wsUrl);
|
|
||||||
|
const wsUrl = this.setupSignature;
|
||||||
|
|
||||||
|
if (typeof wsUrl !== 'string') {
|
||||||
|
throw new Error('setupSignature must be a string');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ws = new WebSocket(wsUrl);
|
||||||
|
|
||||||
this.ws.onmessage = (event) => {
|
this.ws.onmessage = (event) => {
|
||||||
try {
|
try {
|
||||||
@ -119,13 +124,19 @@ export class MessageBridge {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private setupNodejsListener() {
|
private setupNodejsListener() {
|
||||||
const EventEmitter = require('events');
|
const { EventEmitter } = require('events');
|
||||||
|
|
||||||
const eventEmitter = new EventEmitter();
|
const emitter = this.setupSignature;
|
||||||
|
if (!(emitter instanceof EventEmitter)) {
|
||||||
|
throw new Error('setupSignature must be an EventEmitter');
|
||||||
|
}
|
||||||
|
|
||||||
|
emitter.on('message/service', (message: VSCodeMessage) => {
|
||||||
|
this.dispatchMessage(message);
|
||||||
|
});
|
||||||
|
|
||||||
this.postMessage = (message) => {
|
this.postMessage = (message) => {
|
||||||
eventEmitter.emit('server', message);
|
emitter.emit('message/renderer', message);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,16 +220,14 @@ export class MessageBridge {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 单例实例
|
// 单例实例
|
||||||
const messageBridge = new MessageBridge();
|
let messageBridge: MessageBridge;
|
||||||
|
|
||||||
// 向外暴露一个独立函数,保证 MessageBridge 是单例的
|
// 向外暴露一个独立函数,保证 MessageBridge 是单例的
|
||||||
export function useMessageBridge() {
|
export function useMessageBridge() {
|
||||||
|
if (!messageBridge) {
|
||||||
|
messageBridge = new MessageBridge('ws://localhost:8080');
|
||||||
|
}
|
||||||
const bridge = messageBridge;
|
const bridge = messageBridge;
|
||||||
|
|
||||||
return {
|
return bridge;
|
||||||
postMessage: bridge.postMessage.bind(bridge),
|
|
||||||
addCommandListener: bridge.addCommandListener.bind(bridge),
|
|
||||||
commandRequest: bridge.commandRequest.bind(bridge),
|
|
||||||
awaitForWebsockt: bridge.awaitForWebsockt.bind(bridge)
|
|
||||||
};
|
|
||||||
}
|
}
|
@ -1,18 +1,20 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import type { Ref } from "vue";
|
import type { Ref } from "vue";
|
||||||
import { ToolCall, ChatStorage, getToolSchema, MessageState } from "../chat-box/chat";
|
import { ToolCall, ChatStorage, getToolSchema, MessageState } from "../chat-box/chat";
|
||||||
import { useMessageBridge } from "@/api/message-bridge";
|
import { useMessageBridge, MessageBridge } from "@/api/message-bridge";
|
||||||
import type { OpenAI } from 'openai';
|
import type { OpenAI } from 'openai';
|
||||||
import { llmManager, llms } from "@/views/setting/llm";
|
import { llmManager, llms } from "@/views/setting/llm";
|
||||||
import { pinkLog, redLog } from "@/views/setting/util";
|
import { pinkLog, redLog } from "@/views/setting/util";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import { handleToolCalls } from "./handle-tool-calls";
|
import { handleToolCalls } from "./handle-tool-calls";
|
||||||
|
import { getPlatform } from "@/api/platform";
|
||||||
|
|
||||||
export type ChatCompletionChunk = OpenAI.Chat.Completions.ChatCompletionChunk;
|
export type ChatCompletionChunk = OpenAI.Chat.Completions.ChatCompletionChunk;
|
||||||
export type ChatCompletionCreateParamsBase = OpenAI.Chat.Completions.ChatCompletionCreateParams & { id?: string };
|
export type ChatCompletionCreateParamsBase = OpenAI.Chat.Completions.ChatCompletionCreateParams & { id?: string };
|
||||||
export interface TaskLoopOptions {
|
export interface TaskLoopOptions {
|
||||||
maxEpochs: number;
|
maxEpochs: number;
|
||||||
maxJsonParseRetry: number;
|
maxJsonParseRetry: number;
|
||||||
|
adapter: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IErrorMssage {
|
export interface IErrorMssage {
|
||||||
@ -29,21 +31,34 @@ export interface IDoConversationResult {
|
|||||||
* @description 对任务循环进行的抽象封装
|
* @description 对任务循环进行的抽象封装
|
||||||
*/
|
*/
|
||||||
export class TaskLoop {
|
export class TaskLoop {
|
||||||
private bridge = useMessageBridge();
|
private bridge: MessageBridge;
|
||||||
private currentChatId = '';
|
private currentChatId = '';
|
||||||
|
private onError: (error: IErrorMssage) => void = (msg) => {};
|
||||||
|
private onChunk: (chunk: ChatCompletionChunk) => void = (chunk) => {};
|
||||||
|
private onDone: () => void = () => {};
|
||||||
|
private onEpoch: () => void = () => {};
|
||||||
private completionUsage: ChatCompletionChunk['usage'] | undefined;
|
private completionUsage: ChatCompletionChunk['usage'] | undefined;
|
||||||
private llmConfig: any;
|
private llmConfig: any;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly streamingContent: Ref<string>,
|
private readonly streamingContent: Ref<string>,
|
||||||
private readonly streamingToolCalls: Ref<ToolCall[]>,
|
private readonly streamingToolCalls: Ref<ToolCall[]>,
|
||||||
private onError: (error: IErrorMssage) => void = (msg) => {},
|
private readonly taskOptions: TaskLoopOptions = { maxEpochs: 20, maxJsonParseRetry: 3, adapter: undefined },
|
||||||
private onChunk: (chunk: ChatCompletionChunk) => void = (chunk) => {},
|
|
||||||
private onDone: () => void = () => {},
|
|
||||||
private onEpoch: () => void = () => {},
|
|
||||||
private readonly taskOptions: TaskLoopOptions = { maxEpochs: 20, maxJsonParseRetry: 3 },
|
|
||||||
) {
|
) {
|
||||||
|
// 根据当前环境决定是否要开启 messageBridge
|
||||||
|
const platform = getPlatform();
|
||||||
|
if (platform === 'nodejs') {
|
||||||
|
|
||||||
|
const adapter = taskOptions.adapter;
|
||||||
|
|
||||||
|
if (!adapter) {
|
||||||
|
throw new Error('adapter is required');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.bridge = new MessageBridge(adapter.emitter);
|
||||||
|
} else {
|
||||||
|
this.bridge = useMessageBridge();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleChunkDeltaContent(chunk: ChatCompletionChunk) {
|
private handleChunkDeltaContent(chunk: ChatCompletionChunk) {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { WebSocket } from 'ws';
|
import { WebSocket } from 'ws';
|
||||||
|
import { EventEmitter } from 'events';
|
||||||
|
|
||||||
// WebSocket 消息格式
|
// WebSocket 消息格式
|
||||||
export interface WebSocketMessage {
|
export interface WebSocketMessage {
|
||||||
@ -63,3 +64,35 @@ export class VSCodeWebViewLike {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export class EventAdapter {
|
||||||
|
public emitter: EventEmitter;
|
||||||
|
private messageHandlers: Set<MessageHandler>;
|
||||||
|
|
||||||
|
constructor(option: any) {
|
||||||
|
this.emitter = new EventEmitter(option);
|
||||||
|
this.messageHandlers = new Set();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送消息
|
||||||
|
* @param message - 包含 command 和 args 的消息
|
||||||
|
*/
|
||||||
|
postMessage(message: WebSocketMessage): void {
|
||||||
|
this.emitter.emit('message/service', message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接收消息
|
||||||
|
* @param callback - 消息回调
|
||||||
|
* @returns {{ dispose: () => void }} - 可销毁的监听器
|
||||||
|
*/
|
||||||
|
onDidReceiveMessage(callback: MessageHandler): { dispose: () => void } {
|
||||||
|
this.messageHandlers.add(callback);
|
||||||
|
return {
|
||||||
|
dispose: () => this.messageHandlers.delete(callback),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
export { routeMessage } from './common/router';
|
export { routeMessage } from './common/router';
|
||||||
export { VSCodeWebViewLike } from './hook/adapter';
|
export { VSCodeWebViewLike, EventAdapter } from './hook/adapter';
|
||||||
export { setVscodeWorkspace, setRunningCWD } from './hook/setting';
|
export { setVscodeWorkspace, setRunningCWD } from './hook/setting';
|
||||||
// TODO: 更加规范
|
// TODO: 更加规范
|
||||||
export { client } from './mcp/connect.service';
|
export { client } from './mcp/connect.service';
|
Loading…
x
Reference in New Issue
Block a user