release parallel test

This commit is contained in:
锦恢 2025-07-13 23:59:02 +08:00
parent 0dc727e781
commit 1c8a447dc7
9 changed files with 66 additions and 22 deletions

View File

@ -1,6 +1,7 @@
import { pinkLog, redLog } from '@/views/setting/util'; import { pinkLog, redLog } from '@/views/setting/util';
import { acquireVsCodeApi, electronApi, getPlatform } from './platform'; import { acquireVsCodeApi, electronApi, getPlatform } from './platform';
import { isReactive } from 'vue'; import { isReactive } from 'vue';
import { v4 as uuidv4 } from 'uuid';
export interface VSCodeMessage { export interface VSCodeMessage {
command: string; command: string;
@ -9,6 +10,7 @@ export interface VSCodeMessage {
} }
export interface RestFulResponse<T = any> { export interface RestFulResponse<T = any> {
_id?: string
code: number; code: number;
msg: T; msg: T;
} }
@ -163,7 +165,7 @@ export class MessageBridge {
const command = message.command; const command = message.command;
const data = message.data; const data = message.data;
const handlers = this.handlers.get(command) || []; const handlers = this.handlers.get(command) || new Set();
handlers.forEach(handler => handler(data)); handlers.forEach(handler => handler(data));
} }
@ -231,15 +233,22 @@ export class MessageBridge {
* @returns * @returns
*/ */
public commandRequest<T = any>(command: string, data?: ICommandRequestData): Promise<RestFulResponse<T>> { public commandRequest<T = any>(command: string, data?: ICommandRequestData): Promise<RestFulResponse<T>> {
const _id = uuidv4();
return new Promise<RestFulResponse>((resolve, reject) => { return new Promise<RestFulResponse>((resolve, reject) => {
this.addCommandListener(command, (data) => { const handler = this.addCommandListener(command, (data) => {
if (data._id === _id) {
handler();
resolve(data as RestFulResponse); resolve(data as RestFulResponse);
}, { once: true }); }
}, { once: false });
this.postMessage({ this.postMessage({
command, command,
data: this.deserializeReactiveData(data) data: this.deserializeReactiveData({
_id,
...data
})
}); });
}); });
} }

View File

@ -221,6 +221,7 @@ export class TaskLoop {
}, { once: false }); }, { once: false });
const doneHandler = this.bridge.addCommandListener('llm/chat/completions/done', data => { const doneHandler = this.bridge.addCommandListener('llm/chat/completions/done', data => {
if (data.sessionId !== sessionId) { if (data.sessionId !== sessionId) {
return; return;
} }
@ -229,11 +230,12 @@ export class TaskLoop {
chunkHandler(); chunkHandler();
errorHandler(); errorHandler();
doneHandler();
resolve({ resolve({
stop: false stop: false
}); });
}, { once: true }); }, { once: false });
const errorHandler = this.bridge.addCommandListener('llm/chat/completions/error', data => { const errorHandler = this.bridge.addCommandListener('llm/chat/completions/error', data => {
if (data.sessionId !== sessionId) { if (data.sessionId !== sessionId) {
@ -246,13 +248,14 @@ export class TaskLoop {
}); });
chunkHandler(); chunkHandler();
errorHandler();
doneHandler(); doneHandler();
resolve({ resolve({
stop: true stop: true
}); });
}, { once: true }); }, { once: false });
this.bridge.postMessage({ this.bridge.postMessage({
command: 'llm/chat/completions', command: 'llm/chat/completions',

View File

@ -182,7 +182,7 @@ const toolcallPercent = computed(() => {
.item-json { .item-json {
border-radius: 4px; border-radius: 4px;
padding: 6px 10px; padding: 6px 10px;
font-size: 15px; font-size: 13px;
font-family: var(--code-font-family, monospace); font-family: var(--code-font-family, monospace);
margin: 2px 0 8px 0; margin: 2px 0 8px 0;
white-space: pre-wrap; white-space: pre-wrap;
@ -193,6 +193,7 @@ const toolcallPercent = computed(() => {
} }
.code-container { .code-container {
font-size: 13px;
margin-top: 10px; margin-top: 10px;
border-radius: .3em; border-radius: .3em;
padding: 0 10px; padding: 0 10px;

View File

@ -51,6 +51,7 @@ export interface NodeDataView {
export interface DiagramContext { export interface DiagramContext {
preset: (type: string) => void, preset: (type: string) => void,
render: () => void, render: () => void,
resetDataView: () => void,
state?: DiagramState, state?: DiagramState,
setCaption: (value: string) => void setCaption: (value: string) => void
} }
@ -178,7 +179,7 @@ export async function makeNodeTest(
context.render(); context.render();
try { try {
const loop = new TaskLoop({ maxEpochs: 1 }); const loop = new TaskLoop({ maxEpochs: 1, verbose: 0 });
const usePrompt = (prompt || 'please call the tool {tool} to make some test').replace('{tool}', dataView.tool.name); const usePrompt = (prompt || 'please call the tool {tool} to make some test').replace('{tool}', dataView.tool.name);
const chatStorage = { const chatStorage = {
messages: [], messages: [],
@ -198,8 +199,6 @@ export async function makeNodeTest(
} }
} as ChatStorage; } as ChatStorage;
loop.setMaxEpochs(1);
let aiMockJson: any = undefined; let aiMockJson: any = undefined;
loop.registerOnToolCall(toolCall => { loop.registerOnToolCall(toolCall => {

View File

@ -188,7 +188,7 @@ const drawDiagram = async () => {
// edges // edges
const reservedEdges = autoDetectDiagram?.edges; const reservedEdges = autoDetectDiagram?.edges;
if (reservedEdges && reservedEdges.length > 0) { if (reservedEdges) {
for (const edge of reservedEdges) { for (const edge of reservedEdges) {
if (edge.sources && edge.targets && edge.sources.length > 0 && edge.targets.length > 0) { if (edge.sources && edge.targets && edge.sources.length > 0 && edge.targets.length > 0) {
edges.push({ edges.push({
@ -662,6 +662,24 @@ function getNodePopupStyle(node: any): any {
height: `${popupHeight}px` height: `${popupHeight}px`
}; };
} }
//
function resetDataView() {
state.dataView.forEach((view, key) => {
state.dataView.set(key, {
...view,
status: 'waiting',
result: null,
createAt: undefined,
finishAt: undefined,
llmTimecost: undefined,
toolcallTimecost: undefined
});
});
}
context.resetDataView = resetDataView;
</script> </script>
<style> <style>

View File

@ -73,7 +73,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, nextTick, provide, ref } from 'vue'; import { computed, nextTick, provide, ref } from 'vue';
import Diagram from './diagram.vue'; import Diagram from './diagram.vue';
import { makeNodeTest, makeParallelTest, topoSortParallel, type DiagramContext, type DiagramState } from './diagram'; import { makeNodeTest, topoSortParallel, type DiagramContext } from './diagram';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
@ -118,6 +118,7 @@ function setCaption(text: string) {
const context: DiagramContext = { const context: DiagramContext = {
preset: () => { }, preset: () => { },
render: () => { }, render: () => { },
resetDataView: () => { },
state: undefined, state: undefined,
setCaption setCaption
}; };
@ -149,6 +150,10 @@ async function onTestConfirm() {
tabStorage.autoDetectDiagram!.views = []; tabStorage.autoDetectDiagram!.views = [];
//
context.resetDataView();
context.render();
if (state) { if (state) {
const dispatches = topoSortParallel(state); const dispatches = topoSortParallel(state);

View File

@ -26,12 +26,18 @@ export async function routeMessage(command: string, data: any, webview: PostMess
// res.code = -1 代表当前请求不需要返回发送 // res.code = -1 代表当前请求不需要返回发送
if (res.code >= 0) { if (res.code >= 0) {
webview.postMessage({ command, data: res }); webview.postMessage({
command, data: {
_id: data._id,
...res
}
});
} }
} catch (error) { } catch (error) {
// console.error(error); // console.error(error);
webview.postMessage({ webview.postMessage({
command, data: { command, data: {
_id: data._id,
code: 500, code: 500,
msg: (error as any).toString() msg: (error as any).toString()
} }

View File

@ -92,6 +92,8 @@ export async function streamingChatCompletion(
} }
} }
console.log('sessionId finish ' + sessionId);
// 传输结束,移除对应的 stream // 传输结束,移除对应的 stream
if (sessionId) { if (sessionId) {
chatStreams.delete(sessionId); chatStreams.delete(sessionId);

View File

@ -110,6 +110,7 @@ wss.on('connection', (ws) => {
webview.postMessage({ webview.postMessage({
command: 'web/launch-signature', command: 'web/launch-signature',
data: { data: {
_id: data._id,
code: 200, code: 200,
msg: option.items msg: option.items
} }