Skip to content

Commit 1b80964

Browse files
committed
Refactor markdown report generation in GenerationStats for improved readability and consistency
1 parent e1c2388 commit 1b80964

File tree

1 file changed

+32
-29
lines changed

1 file changed

+32
-29
lines changed

packages/core/src/usage.ts

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -411,24 +411,24 @@ export class GenerationStats {
411411

412412
/**
413413
* Generates a compact markdown report suitable for GitHub comments.
414-
*
414+
*
415415
* The report contains:
416416
* - A collapsible `<details>` section with aggregate usage statistics in the summary
417417
* - A table showing individual LLM call details including model, tokens, costs, and duration
418418
* - Proper formatting for tokens (t, kt, Mt) and costs (¢, $)
419419
* - Duration formatting (ms, s, m, h)
420-
*
421-
* @returns A markdown string with a details section containing aggregate results
420+
*
421+
* @returns A markdown string with a details section containing aggregate results
422422
* as summary and a table with individual LLM call usage, tokens, and costs.
423-
*
423+
*
424424
* @example
425425
* ```typescript
426426
* const stats = new GenerationStats("openai:gpt-4", "main");
427427
* stats.addUsage({ prompt_tokens: 100, completion_tokens: 50, total_tokens: 150, duration: 1000 }, 1000);
428-
*
428+
*
429429
* const child = stats.createChild("openai:gpt-3.5-turbo", "helper");
430430
* child.addUsage({ prompt_tokens: 200, completion_tokens: 100, total_tokens: 300, duration: 2000 }, 2000);
431-
*
431+
*
432432
* const report = stats.toMarkdownReport();
433433
* // Returns:
434434
* // <details>
@@ -443,17 +443,17 @@ export class GenerationStats {
443443
toMarkdownReport(): string {
444444
const accumulated = this.accumulatedUsage();
445445
const totalCost = this.cost();
446-
446+
447447
// Create summary with aggregate statistics
448448
const summaryParts = [
449449
`💰 Usage Report`,
450-
prettyTokens(accumulated.total_tokens) || "0t",
450+
prettyTokens(accumulated.total_tokens, "both"),
451451
prettyCost(totalCost),
452452
prettyDuration(accumulated.duration),
453-
].filter(part => !!part);
454-
453+
].filter((part) => !!part);
454+
455455
const summary = summaryParts.join(" ");
456-
456+
457457
// Collect all usage data (parent + children)
458458
const usageData: Array<{
459459
Model: string;
@@ -464,47 +464,50 @@ export class GenerationStats {
464464
$: string;
465465
"⏱️": string;
466466
}> = [];
467-
467+
468468
// Add parent stats if it has usage
469469
if (this.usage.total_tokens > 0) {
470470
// For parent, calculate cost from actual usage or use existing cost calculation
471-
const parentCost = this.chatTurns.length > 0
472-
? this.chatTurns
473-
.filter(turn => !turn.cached)
474-
.map(turn => estimateCost(turn.model, turn.usage) ?? estimateCost(this.model, turn.usage))
475-
.reduce((a, b) => (a ?? 0) + (b ?? 0), 0)
476-
: estimateCost(this.model, this.usage);
477-
471+
const parentCost =
472+
this.chatTurns.length > 0
473+
? this.chatTurns
474+
.filter((turn) => !turn.cached)
475+
.map(
476+
(turn) =>
477+
estimateCost(turn.model, turn.usage) ?? estimateCost(this.model, turn.usage),
478+
)
479+
.reduce((a, b) => (a ?? 0) + (b ?? 0), 0)
480+
: estimateCost(this.model, this.usage);
481+
478482
usageData.push({
479483
Model: this.resolvedModel,
480484
Label: this.label || "-",
481485
[CHAR_UP_ARROW]: prettyTokens(this.usage.prompt_tokens) || "0t",
482-
[CHAR_DOWN_ARROW]: prettyTokens(this.usage.completion_tokens) || "0t",
486+
[CHAR_DOWN_ARROW]: prettyTokens(this.usage.completion_tokens) || "0t",
483487
[CHAR_UP_DOWN_ARROWS]: prettyTokens(this.usage.total_tokens) || "0t",
484488
$: prettyCost(parentCost) || "-",
485489
"⏱️": prettyDuration(this.usage.duration) || "-",
486490
});
487491
}
488-
492+
489493
// Add children stats
490494
for (const child of this.children) {
491495
const childUsage = child.accumulatedUsage();
492496
// Calculate cost for child - try existing cost calculation first, then estimate from usage
493-
const childCost = child.chatTurns.length > 0
494-
? child.cost()
495-
: estimateCost(child.model, childUsage);
496-
497+
const childCost =
498+
child.chatTurns.length > 0 ? child.cost() : estimateCost(child.model, childUsage);
499+
497500
usageData.push({
498501
Model: child.resolvedModel,
499502
Label: child.label || "-",
500503
[CHAR_UP_ARROW]: prettyTokens(childUsage.prompt_tokens) || "0t",
501504
[CHAR_DOWN_ARROW]: prettyTokens(childUsage.completion_tokens) || "0t",
502-
[CHAR_UP_DOWN_ARROWS]: prettyTokens(childUsage.total_tokens) || "0t",
505+
[CHAR_UP_DOWN_ARROWS]: prettyTokens(childUsage.total_tokens) || "0t",
503506
$: prettyCost(childCost) || "-",
504507
"⏱️": prettyDuration(childUsage.duration) || "-",
505508
});
506509
}
507-
510+
508511
// If no usage data, add a placeholder row
509512
if (usageData.length === 0) {
510513
usageData.push({
@@ -517,10 +520,10 @@ export class GenerationStats {
517520
"⏱️": "-",
518521
});
519522
}
520-
523+
521524
// Generate markdown table
522525
const table = dataToMarkdownTable(usageData);
523-
526+
524527
return details(summary, table);
525528
}
526529
}

0 commit comments

Comments
 (0)