@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
JavaScript
;
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;