From 4281d2955d0e5892dcf8334e79cf1c8847fbe513 Mon Sep 17 00:00:00 2001 From: Cascade Bot Date: Mon, 16 Mar 2026 20:00:07 +0000 Subject: [PATCH] refactor(utils): remove dead utility functions from metrics, trigger utils, and media --- src/pm/media.ts | 12 ---- src/triggers/github/utils.ts | 52 ---------------- src/utils/llmMetrics.ts | 59 +----------------- tests/unit/pm/media.test.ts | 25 -------- tests/unit/triggers/github-utils.test.ts | 46 -------------- tests/unit/utils/llmMetrics.test.ts | 78 +----------------------- 6 files changed, 3 insertions(+), 269 deletions(-) diff --git a/src/pm/media.ts b/src/pm/media.ts index f1ed05e4..b6e33f4c 100644 --- a/src/pm/media.ts +++ b/src/pm/media.ts @@ -269,18 +269,6 @@ export async function downloadMedia( } } -/** - * Converts a downloaded media buffer to a base64 data URI string suitable - * for embedding in HTML or LLM context. - * - * @param buffer - The raw bytes of the media. - * @param mimeType - The MIME type of the media (e.g. `'image/png'`). - * @returns A base64 data URI string, e.g. `'data:image/png;base64,iVBORw...'`. - */ -export function mediaToBase64DataUri(buffer: Buffer, mimeType: string): string { - return `data:${mimeType};base64,${buffer.toString('base64')}`; -} - // --------------------------------------------------------------------------- // JIRA media URL resolution // --------------------------------------------------------------------------- diff --git a/src/triggers/github/utils.ts b/src/triggers/github/utils.ts index 6b987054..699fe0d1 100644 --- a/src/triggers/github/utils.ts +++ b/src/triggers/github/utils.ts @@ -64,39 +64,6 @@ export function extractTrelloCardId(text: string | null): string | null { return match ? match[1] : null; } -/** - * Check if text contains a Trello card URL. - */ -export function hasTrelloCardUrl(text: string | null): boolean { - return extractTrelloCardId(text) !== null; -} - -/** - * Extract full Trello card URL from text. - */ -export function extractTrelloCardUrl(text: string | null): string | null { - if (!text) return null; - const match = text.match(TRELLO_CARD_URL_REGEX); - return match ? match[0] : null; -} - -/** - * Validate PR body has Trello card URL and extract card ID. - * Returns card ID or null (with logging) if not found. - */ -export function requireTrelloCardId( - prBody: string | null, - context: { prNumber: number; triggerName: string }, -): string | null { - if (!hasTrelloCardUrl(prBody)) { - logger.info(`PR does not have Trello card URL, skipping ${context.triggerName}`, { - prNumber: context.prNumber, - }); - return null; - } - return extractTrelloCardId(prBody); -} - /** * Extract a JIRA issue key (e.g., "PROJ-123") from text. */ @@ -119,25 +86,6 @@ export function extractWorkItemId(text: string | null, project: ProjectConfig): return extractTrelloCardId(text); } -/** - * Validate PR body has a work item reference and extract the ID. - * Works for both Trello (card URL) and JIRA (issue key) projects. - */ -export function requireWorkItemId( - prBody: string | null, - project: ProjectConfig, - context: { prNumber: number; triggerName: string }, -): string | null { - const id = extractWorkItemId(prBody, project); - if (!id) { - logger.info(`PR does not have work item reference, skipping ${context.triggerName}`, { - prNumber: context.prNumber, - pmType: project.pm?.type ?? 'trello', - }); - } - return id; -} - /** * Resolve work item ID for a PR using DB lookup only (pr_work_items table). * Returns undefined when DB returns null or throws. diff --git a/src/utils/llmMetrics.ts b/src/utils/llmMetrics.ts index 316e9c21..97a3b2bb 100644 --- a/src/utils/llmMetrics.ts +++ b/src/utils/llmMetrics.ts @@ -1,16 +1,9 @@ /** * LLM request metrics tracking and logging utilities. - * Provides cost calculation, token estimation, and structured logging. + * Provides cost calculation. */ import type { TokenUsage } from 'llmist'; -/** - * Simple logger interface matching CASCADE's logger. - */ -interface SimpleLogger { - info(message: string, context?: Record): void; -} - /** * Model pricing per 1M tokens (in USD). * Prices as of January 2026. @@ -43,16 +36,6 @@ const MODEL_PRICING: Record { }); }); -// --------------------------------------------------------------------------- -// mediaToBase64DataUri -// --------------------------------------------------------------------------- - -describe('mediaToBase64DataUri', () => { - it('returns a correctly formatted data URI', () => { - const buffer = Buffer.from('hello'); - const result = mediaToBase64DataUri(buffer, 'image/png'); - expect(result).toBe(`data:image/png;base64,${Buffer.from('hello').toString('base64')}`); - }); - - it('works for different MIME types', () => { - const buffer = Buffer.from([0xff, 0xd8, 0xff]); - const result = mediaToBase64DataUri(buffer, 'image/jpeg'); - expect(result).toMatch(/^data:image\/jpeg;base64,/); - }); - - it('empty buffer produces valid (empty content) data URI', () => { - const buffer = Buffer.alloc(0); - const result = mediaToBase64DataUri(buffer, 'image/gif'); - expect(result).toBe('data:image/gif;base64,'); - }); -}); - // --------------------------------------------------------------------------- // resolveJiraMediaUrls // --------------------------------------------------------------------------- diff --git a/tests/unit/triggers/github-utils.test.ts b/tests/unit/triggers/github-utils.test.ts index 5b67c4e1..95aa0cd4 100644 --- a/tests/unit/triggers/github-utils.test.ts +++ b/tests/unit/triggers/github-utils.test.ts @@ -9,8 +9,6 @@ import { extractJiraIssueKey, extractTrelloCardId, extractWorkItemId, - hasTrelloCardUrl, - requireWorkItemId, resolveWorkItemId, } from '../../../src/triggers/github/utils.js'; import type { ProjectConfig } from '../../../src/types/index.js'; @@ -72,24 +70,6 @@ describe('extractTrelloCardId', () => { }); }); -describe('hasTrelloCardUrl', () => { - it('returns false for null input', () => { - expect(hasTrelloCardUrl(null)).toBe(false); - }); - - it('returns false for text without URL', () => { - expect(hasTrelloCardUrl('No URL here')).toBe(false); - }); - - it('returns true for text with Trello URL', () => { - expect(hasTrelloCardUrl('https://trello.com/c/abc123/card')).toBe(true); - }); - - it('returns true for partial match in longer text', () => { - expect(hasTrelloCardUrl('Check out this card: https://trello.com/c/xyz789')).toBe(true); - }); -}); - describe('extractJiraIssueKey', () => { it('returns null for null input', () => { expect(extractJiraIssueKey(null)).toBeNull(); @@ -153,32 +133,6 @@ describe('extractWorkItemId', () => { }); }); -describe('requireWorkItemId', () => { - const context = { prNumber: 42, triggerName: 'test-trigger' }; - - it('returns null when no ID found', () => { - const result = requireWorkItemId('No work item reference', mockTrelloProject, context); - expect(result).toBeNull(); - }); - - it('returns ID when present in Trello project', () => { - const text = 'Implements https://trello.com/c/abc123/card'; - const result = requireWorkItemId(text, mockTrelloProject, context); - expect(result).toBe('abc123'); - }); - - it('returns ID when present in JIRA project', () => { - const text = 'Fixes PROJ-789'; - const result = requireWorkItemId(text, mockJiraProject, context); - expect(result).toBe('PROJ-789'); - }); - - it('returns null for null input', () => { - const result = requireWorkItemId(null, mockTrelloProject, context); - expect(result).toBeNull(); - }); -}); - describe('resolveWorkItemId', () => { beforeEach(() => { vi.mocked(lookupWorkItemForPR).mockResolvedValue(null); diff --git a/tests/unit/utils/llmMetrics.test.ts b/tests/unit/utils/llmMetrics.test.ts index 28e2cc82..d3df3b05 100644 --- a/tests/unit/utils/llmMetrics.test.ts +++ b/tests/unit/utils/llmMetrics.test.ts @@ -1,10 +1,5 @@ -import { describe, expect, it, vi } from 'vitest'; -import { - calculateCost, - estimateInputTokens, - logLLMCallStart, - logLLMMetrics, -} from '../../../src/utils/llmMetrics.js'; +import { describe, expect, it } from 'vitest'; +import { calculateCost } from '../../../src/utils/llmMetrics.js'; describe.concurrent('llmMetrics', () => { describe('calculateCost', () => { @@ -76,73 +71,4 @@ describe.concurrent('llmMetrics', () => { expect(cost).toBeCloseTo(0.00015 + 0.0003, 8); }); }); - - describe('estimateInputTokens', () => { - it('estimates tokens from messages', () => { - const messages = [{ role: 'user', content: 'Hello world' }]; - const estimate = estimateInputTokens(messages); - - // JSON.stringify length / 4, ceiling - expect(estimate).toBeGreaterThan(0); - expect(estimate).toBe(Math.ceil(JSON.stringify(messages).length / 4)); - }); - - it('handles empty messages array', () => { - const estimate = estimateInputTokens([]); - - expect(estimate).toBeGreaterThan(0); // [] still has length 2 - }); - - it('handles large messages', () => { - const longContent = 'a'.repeat(4000); - const messages = [{ role: 'user', content: longContent }]; - const estimate = estimateInputTokens(messages); - - expect(estimate).toBeGreaterThanOrEqual(1000); - }); - }); - - describe('logLLMMetrics', () => { - it('logs metrics with formatted cost', () => { - const mockLogger = { info: vi.fn() }; - - logLLMMetrics(mockLogger, { - model: 'test-model', - iteration: 5, - inputTokens: 1000, - outputTokens: 500, - cachedTokens: 200, - durationMs: 1500, - cost: 0.003456, - }); - - expect(mockLogger.info).toHaveBeenCalledWith('LLM call complete', { - model: 'test-model', - iteration: 5, - inputTokens: 1000, - outputTokens: 500, - cachedTokens: 200, - durationMs: 1500, - cost: '$0.003456', - }); - }); - }); - - describe('logLLMCallStart', () => { - it('logs call start with estimated tokens and message count', () => { - const mockLogger = { info: vi.fn() }; - const messages = [ - { role: 'system', content: 'You are helpful' }, - { role: 'user', content: 'Hello' }, - ]; - - logLLMCallStart(mockLogger, 3, messages); - - expect(mockLogger.info).toHaveBeenCalledWith('LLM call starting', { - iteration: 3, - estimatedInputTokens: expect.any(Number), - messageCount: 2, - }); - }); - }); });