( metrics: PromptMetrics, derivedMetrics: NonNullable<TestSuite['derivedMetrics']>, evalStep: RunEvalOptions, promptEvalCount: number, )
| 1762 | } |
| 1763 | |
| 1764 | async function updateDerivedMetrics( |
| 1765 | metrics: PromptMetrics, |
| 1766 | derivedMetrics: NonNullable<TestSuite['derivedMetrics']>, |
| 1767 | evalStep: RunEvalOptions, |
| 1768 | promptEvalCount: number, |
| 1769 | ) { |
| 1770 | const math = await import('mathjs'); |
| 1771 | if (Object.prototype.hasOwnProperty.call(metrics.namedScores, '__count')) { |
| 1772 | logger.warn("Metric name '__count' is reserved for derived metrics and will be overridden."); |
| 1773 | } |
| 1774 | |
| 1775 | const evalContext: Record<string, number> = { |
| 1776 | ...metrics.namedScores, |
| 1777 | __count: promptEvalCount, |
| 1778 | }; |
| 1779 | for (const metric of derivedMetrics) { |
| 1780 | metrics.namedScores[metric.name] ??= 0; |
| 1781 | try { |
| 1782 | metrics.namedScores[metric.name] = |
| 1783 | typeof metric.value === 'function' |
| 1784 | ? metric.value(evalContext, evalStep) |
| 1785 | : math.evaluate(metric.value, evalContext); |
| 1786 | evalContext[metric.name] = metrics.namedScores[metric.name]; |
| 1787 | } catch (error) { |
| 1788 | logger.debug( |
| 1789 | `Could not evaluate derived metric '${metric.name}': ${(error as Error).message}`, |
| 1790 | ); |
| 1791 | } |
| 1792 | } |
| 1793 | } |
| 1794 | |
| 1795 | function updateComparisonReporterTotals({ |
| 1796 | ciProgressReporter, |
no test coverage detected
searching dependent graphs…