@yhong91/vibetime 0.1.39 → 0.1.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/vibetime.mjs +74 -27
- package/package.json +1 -1
package/bin/vibetime.mjs
CHANGED
|
@@ -1928,7 +1928,7 @@ function countTextLines(text) {
|
|
|
1928
1928
|
}
|
|
1929
1929
|
|
|
1930
1930
|
// src/lib/constants.ts
|
|
1931
|
-
var PACKAGE_VERSION = true ? "0.1.
|
|
1931
|
+
var PACKAGE_VERSION = true ? "0.1.40" : "0.1.1";
|
|
1932
1932
|
var DEFAULT_API_URL = "http://121.196.224.82:3001";
|
|
1933
1933
|
var DEFAULT_BACKFILL_BATCH_SIZE = 50;
|
|
1934
1934
|
var DEFAULT_BACKFILL_BATCH_BYTES = 800 * 1024;
|
|
@@ -4565,48 +4565,71 @@ function normalizeModelCandidate(value) {
|
|
|
4565
4565
|
}
|
|
4566
4566
|
return trimmed;
|
|
4567
4567
|
}
|
|
4568
|
-
function
|
|
4569
|
-
|
|
4570
|
-
if (!Array.isArray(parsed) || parsed.length === 0) {
|
|
4571
|
-
return void 0;
|
|
4572
|
-
}
|
|
4573
|
-
const first = parsed[0];
|
|
4574
|
-
if (!isPlainObject(first)) {
|
|
4575
|
-
return void 0;
|
|
4576
|
-
}
|
|
4577
|
-
const usage = objectField(first, "usage");
|
|
4578
|
-
if (!isPlainObject(usage)) {
|
|
4568
|
+
function finitePositive(value) {
|
|
4569
|
+
if (typeof value !== "number" && typeof value !== "string") {
|
|
4579
4570
|
return void 0;
|
|
4580
4571
|
}
|
|
4572
|
+
const parsed = Number(value);
|
|
4573
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : void 0;
|
|
4574
|
+
}
|
|
4575
|
+
function extractUsageFromGenerationSpan(span) {
|
|
4576
|
+
const parsed = parseEmbeddedJson(span.toolOutput);
|
|
4577
|
+
const first = Array.isArray(parsed) ? parsed[0] : void 0;
|
|
4578
|
+
const usage = isPlainObject(first) ? objectField(first, "usage") : {};
|
|
4581
4579
|
const inputTokens = numberField(usage, "prompt_tokens");
|
|
4582
4580
|
const outputTokens = numberField(usage, "completion_tokens");
|
|
4583
4581
|
const totalTokens = numberField(usage, "total_tokens");
|
|
4584
4582
|
const details = objectField(usage, "prompt_tokens_details");
|
|
4585
4583
|
const cachedTokens = isPlainObject(details) ? numberField(details, "cached_tokens") : void 0;
|
|
4584
|
+
const otelAttributes = span.attributes || {};
|
|
4585
|
+
const otelInputTokens = finitePositive(otelAttributes["gen_ai.usage.input_tokens"]);
|
|
4586
|
+
const otelOutputTokens = finitePositive(otelAttributes["gen_ai.usage.output_tokens"]);
|
|
4587
|
+
const otelCacheReadTokens = finitePositive(otelAttributes["gen_ai.usage.cache_read_input_tokens"]);
|
|
4588
|
+
const otelCacheCreationTokens = finitePositive(otelAttributes["gen_ai.usage.cache_creation_input_tokens"]);
|
|
4589
|
+
const otelReasoningTokens = finitePositive(otelAttributes["gen_ai.usage.reasoning_output_tokens"]);
|
|
4590
|
+
const tokensInput = otelInputTokens ?? inputTokens;
|
|
4591
|
+
const tokensOutput = otelOutputTokens ?? outputTokens;
|
|
4592
|
+
const tokensCacheReadInput = otelCacheReadTokens ?? cachedTokens;
|
|
4593
|
+
const tokensCachedInput = (tokensCacheReadInput ?? 0) + (otelCacheCreationTokens ?? 0);
|
|
4594
|
+
const tokensTotal = totalTokens || (tokensInput ?? 0) + (tokensOutput ?? 0);
|
|
4595
|
+
if (!tokensInput && !tokensOutput && !tokensCachedInput && !otelReasoningTokens && !tokensTotal) {
|
|
4596
|
+
return void 0;
|
|
4597
|
+
}
|
|
4586
4598
|
return {
|
|
4587
|
-
tokensInput:
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4599
|
+
tokensInput: tokensInput || void 0,
|
|
4600
|
+
tokensOutput: tokensOutput || void 0,
|
|
4601
|
+
tokensCachedInput: tokensCachedInput || void 0,
|
|
4602
|
+
tokensCacheReadInput: tokensCacheReadInput || void 0,
|
|
4603
|
+
tokensCacheCreationInput: otelCacheCreationTokens,
|
|
4604
|
+
tokensReasoningOutput: otelReasoningTokens,
|
|
4605
|
+
tokensTotal: tokensTotal || void 0,
|
|
4592
4606
|
modelCalls: 1
|
|
4593
4607
|
};
|
|
4594
4608
|
}
|
|
4595
4609
|
function modelUsageFromTrace(trace, generationIndex, totalGenerations) {
|
|
4596
4610
|
const info = trace.modelInfo;
|
|
4597
|
-
|
|
4611
|
+
const otelAttributes = trace.attributes || {};
|
|
4612
|
+
const otelInputTokens = finitePositive(otelAttributes["gen_ai.usage.input_tokens"]);
|
|
4613
|
+
const otelOutputTokens = finitePositive(otelAttributes["gen_ai.usage.output_tokens"]);
|
|
4614
|
+
const otelCacheReadTokens = finitePositive(otelAttributes["gen_ai.usage.cache_read_input_tokens"]);
|
|
4615
|
+
const otelCacheCreationTokens = finitePositive(otelAttributes["gen_ai.usage.cache_creation_input_tokens"]);
|
|
4616
|
+
const otelReasoningTokens = finitePositive(otelAttributes["gen_ai.usage.reasoning_output_tokens"]);
|
|
4617
|
+
if (!info && !trace.totalTokens && !otelInputTokens && !otelOutputTokens && !otelCacheReadTokens && !otelCacheCreationTokens && !otelReasoningTokens) {
|
|
4598
4618
|
return void 0;
|
|
4599
4619
|
}
|
|
4620
|
+
const inputTokens = otelInputTokens ?? (info?.totalInputTokens || 0);
|
|
4621
|
+
const outputTokens = otelOutputTokens ?? (info?.totalOutputTokens || 0);
|
|
4622
|
+
const cacheReadTokens = otelCacheReadTokens ?? info?.totalCachedTokens;
|
|
4623
|
+
const cachedTokens = (cacheReadTokens ?? 0) + (otelCacheCreationTokens ?? 0);
|
|
4624
|
+
const totalTokens = trace.totalTokens || inputTokens + outputTokens;
|
|
4600
4625
|
if (generationIndex === 1) {
|
|
4601
|
-
const inputTokens = info.totalInputTokens || 0;
|
|
4602
|
-
const outputTokens = info.totalOutputTokens || 0;
|
|
4603
|
-
const cachedTokens = info.totalCachedTokens || 0;
|
|
4604
|
-
const totalTokens = trace.totalTokens || inputTokens + outputTokens;
|
|
4605
4626
|
return {
|
|
4606
4627
|
tokensInput: inputTokens || void 0,
|
|
4607
4628
|
tokensCachedInput: cachedTokens || void 0,
|
|
4608
|
-
tokensCacheReadInput:
|
|
4629
|
+
tokensCacheReadInput: cacheReadTokens,
|
|
4630
|
+
tokensCacheCreationInput: otelCacheCreationTokens || void 0,
|
|
4609
4631
|
tokensOutput: outputTokens || void 0,
|
|
4632
|
+
tokensReasoningOutput: otelReasoningTokens || void 0,
|
|
4610
4633
|
tokensTotal: totalTokens || void 0,
|
|
4611
4634
|
modelCalls: totalGenerations || 1
|
|
4612
4635
|
};
|
|
@@ -7617,9 +7640,8 @@ function rebuildEventIdentity2(event) {
|
|
|
7617
7640
|
}
|
|
7618
7641
|
};
|
|
7619
7642
|
}
|
|
7620
|
-
async function
|
|
7643
|
+
async function parseModelNamesFromDynamicTexts(dynamicTextsPath) {
|
|
7621
7644
|
try {
|
|
7622
|
-
const dynamicTextsPath = path17.join(configDir2, ".auth", "dynamic-texts.json");
|
|
7623
7645
|
const content = await readFile10(dynamicTextsPath, "utf8");
|
|
7624
7646
|
const json = JSON.parse(content);
|
|
7625
7647
|
const texts = json.texts || {};
|
|
@@ -7635,6 +7657,19 @@ async function loadQoderCnModelNames(configDir2) {
|
|
|
7635
7657
|
return {};
|
|
7636
7658
|
}
|
|
7637
7659
|
}
|
|
7660
|
+
async function loadQoderCnModelNames(configDir2) {
|
|
7661
|
+
const map = await parseModelNamesFromDynamicTexts(path17.join(configDir2, ".auth", "dynamic-texts.json"));
|
|
7662
|
+
const siblingConfigDir = configDir2.replace(/\.qoder-cn$/, ".qoder");
|
|
7663
|
+
if (siblingConfigDir !== configDir2) {
|
|
7664
|
+
const siblingMap = await parseModelNamesFromDynamicTexts(path17.join(siblingConfigDir, ".auth", "dynamic-texts.json"));
|
|
7665
|
+
for (const [key, val] of Object.entries(siblingMap)) {
|
|
7666
|
+
if (!(key in map)) {
|
|
7667
|
+
map[key] = val;
|
|
7668
|
+
}
|
|
7669
|
+
}
|
|
7670
|
+
}
|
|
7671
|
+
return map;
|
|
7672
|
+
}
|
|
7638
7673
|
async function loadQoderCnSegmentModelCalls(filePath, isSubagentSession, modelMap) {
|
|
7639
7674
|
const { configDir: configDir2, projectName, sessionId } = parseQoderCnPaths(filePath);
|
|
7640
7675
|
const segmentsPath = path17.join(configDir2, "logs", "sessions", projectName, sessionId, "segments");
|
|
@@ -8420,9 +8455,8 @@ function rebuildEventIdentity3(event) {
|
|
|
8420
8455
|
}
|
|
8421
8456
|
};
|
|
8422
8457
|
}
|
|
8423
|
-
async function
|
|
8458
|
+
async function parseModelNamesFromDynamicTexts2(dynamicTextsPath) {
|
|
8424
8459
|
try {
|
|
8425
|
-
const dynamicTextsPath = path18.join(configDir2, ".auth", "dynamic-texts.json");
|
|
8426
8460
|
const content = await readFile11(dynamicTextsPath, "utf8");
|
|
8427
8461
|
const json = JSON.parse(content);
|
|
8428
8462
|
const texts = json.texts || {};
|
|
@@ -8438,6 +8472,19 @@ async function loadQoderModelNames(configDir2) {
|
|
|
8438
8472
|
return {};
|
|
8439
8473
|
}
|
|
8440
8474
|
}
|
|
8475
|
+
async function loadQoderModelNames(configDir2) {
|
|
8476
|
+
const map = await parseModelNamesFromDynamicTexts2(path18.join(configDir2, ".auth", "dynamic-texts.json"));
|
|
8477
|
+
const siblingConfigDir = configDir2.replace(/\.qoder$/, ".qoder-cn");
|
|
8478
|
+
if (siblingConfigDir !== configDir2) {
|
|
8479
|
+
const siblingMap = await parseModelNamesFromDynamicTexts2(path18.join(siblingConfigDir, ".auth", "dynamic-texts.json"));
|
|
8480
|
+
for (const [key, val] of Object.entries(siblingMap)) {
|
|
8481
|
+
if (!(key in map)) {
|
|
8482
|
+
map[key] = val;
|
|
8483
|
+
}
|
|
8484
|
+
}
|
|
8485
|
+
}
|
|
8486
|
+
return map;
|
|
8487
|
+
}
|
|
8441
8488
|
async function loadQoderSegmentModelCalls(filePath, isSubagentSession, modelMap) {
|
|
8442
8489
|
const { configDir: configDir2, projectName, sessionId } = parseQoderPaths(filePath);
|
|
8443
8490
|
const segmentsPath = path18.join(configDir2, "logs", "sessions", projectName, sessionId, "segments");
|
package/package.json
CHANGED