UNPKG

@agentscope/studio

Version:

AgentScope Studio is a powerful local monitoring and visualization tool designed to provide real-time insights into your system's performance and behavior.

155 lines (154 loc) 8.07 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ModelInvocationDao = void 0; const ModelInvocation_1 = require("../models/ModelInvocation"); const ModelInvocationView_1 = require("../models/ModelInvocationView"); class ModelInvocationDao { static saveModelInvocation(data) { return __awaiter(this, void 0, void 0, function* () { try { const newModelInvocation = ModelInvocation_1.ModelInvocationTable.create(Object.assign({}, data)); yield newModelInvocation.save(); } catch (error) { console.error(error); throw error; } }); } static getModelInvocationViewData() { return __awaiter(this, void 0, void 0, function* () { const res = yield ModelInvocationView_1.ModelInvocationView.find(); if (res.length > 0) { return res[0]; } else { throw new Error('RunView data not found'); } }); } static getModeInvocationData(runId) { return __awaiter(this, void 0, void 0, function* () { // 1. 基础统计 const basicStats = yield ModelInvocation_1.ModelInvocationTable.createQueryBuilder('invocation') .select('COUNT(*) as totalInvocations') .addSelect(`COUNT(CASE WHEN invocation.usage->>'type' = :chatType THEN 1 END) as chatInvocations`) .setParameter('chatType', 'chat') .where('invocation.runId = :runId', { runId }) .getRawOne(); // 2. Chat类型的token统计(总计和平均值) const chatTokenStats = yield ModelInvocation_1.ModelInvocationTable.createQueryBuilder('invocation') .select([ // 总计 - prompt tokens `COALESCE(SUM( CASE WHEN invocation.usage->>'type' = :chatType THEN CAST(invocation.usage->'usage'->>'prompt_tokens' AS INTEGER) ELSE 0 END ), 0) as totalPromptTokens`, // 总计 - completion tokens `COALESCE(SUM( CASE WHEN invocation.usage->>'type' = :chatType THEN CAST(invocation.usage->'usage'->>'completion_tokens' AS INTEGER) ELSE 0 END ), 0) as totalCompletionTokens`, // 平均 - prompt tokens `COALESCE( CAST(SUM( CASE WHEN invocation.usage->>'type' = :chatType THEN CAST(invocation.usage->'usage'->>'prompt_tokens' AS INTEGER) ELSE 0 END ) AS FLOAT) / NULLIF(COUNT(CASE WHEN invocation.usage->>'type' = :chatType THEN 1 END), 0) , 0) as avgPromptTokens`, // 平均 - completion tokens `COALESCE( CAST(SUM( CASE WHEN invocation.usage->>'type' = :chatType THEN CAST(invocation.usage->'usage'->>'completion_tokens' AS INTEGER) ELSE 0 END ) AS FLOAT) / NULLIF(COUNT(CASE WHEN invocation.usage->>'type' = :chatType THEN 1 END), 0) , 0) as avgCompletionTokens`, ]) .setParameter('chatType', 'chat') .where('invocation.runId = :runId', { runId }) .getRawOne(); // 3. 按模型分组的调用次数 const modelInvocations = yield ModelInvocation_1.ModelInvocationTable.createQueryBuilder('invocation') .select([ 'invocation.modelName as modelName', 'COUNT(*) as invocations', ]) .where('invocation.runId = :runId', { runId }) .andWhere("invocation.usage->>'type' = :chatType", { chatType: 'chat', }) .groupBy('invocation.modelName') .getRawMany(); // 4. 按模型分组的token统计 const modelTokenStats = yield ModelInvocation_1.ModelInvocationTable.createQueryBuilder('invocation') .select([ 'invocation.modelName as modelName', // 总计 `SUM(CAST(invocation.usage->'usage'->>'prompt_tokens' AS INTEGER)) as totalPromptTokens`, `SUM(CAST(invocation.usage->'usage'->>'completion_tokens' AS INTEGER)) as totalCompletionTokens`, // 平均值 `CAST(SUM(CAST(invocation.usage->'usage'->>'prompt_tokens' AS INTEGER)) AS FLOAT) / COUNT(*) as avgPromptTokens`, `CAST(SUM(CAST(invocation.usage->'usage'->>'completion_tokens' AS INTEGER)) AS FLOAT) / COUNT(*) as avgCompletionTokens`, ]) .where('invocation.runId = :runId', { runId }) .andWhere("invocation.usage->>'type' = :chatType", { chatType: 'chat', }) .groupBy('invocation.modelName') .getRawMany(); // 5. 构建返回结构 return { modelInvocations: Number(basicStats.totalInvocations), chat: { modelInvocations: Number(basicStats.chatInvocations), totalTokens: { promptTokens: Number(chatTokenStats.totalPromptTokens), completionTokens: Number(chatTokenStats.totalCompletionTokens), totalTokens: Number(chatTokenStats.totalPromptTokens) + Number(chatTokenStats.totalCompletionTokens), }, avgTokens: { promptTokens: Number(chatTokenStats.avgPromptTokens), completionTokens: Number(chatTokenStats.avgCompletionTokens), totalTokens: Number(chatTokenStats.avgPromptTokens) + Number(chatTokenStats.avgCompletionTokens), }, modelInvocationsByModel: modelInvocations.map((stat) => ({ modelName: stat.modelName || 'unknown', invocations: Number(stat.invocations), })), totalTokensByModel: modelTokenStats.map((stat) => ({ modelName: stat.modelName || 'unknown', promptTokens: Number(stat.totalPromptTokens), completionTokens: Number(stat.totalCompletionTokens), totalTokens: Number(stat.totalPromptTokens) + Number(stat.totalCompletionTokens), })), avgTokensByModel: modelTokenStats.map((stat) => ({ modelName: stat.modelName || 'unknown', promptTokens: Number(stat.avgPromptTokens), completionTokens: Number(stat.avgCompletionTokens), totalTokens: Number(stat.avgPromptTokens) + Number(stat.avgCompletionTokens), })), }, }; }); } } exports.ModelInvocationDao = ModelInvocationDao;