* Fetch mode rankings data from PostHog * * Queries PostHog for model usage across all modes in the last 7 days * and returns structured data ready for database updates
()
| 63 | * and returns structured data ready for database updates |
| 64 | */ |
| 65 | async function fetchModeRankingsData(): Promise<ModelChartDataUpdates> { |
| 66 | console.log('[sync-internal-data] Fetching model usage data from PostHog...'); |
| 67 | |
| 68 | // Query PostHog using the materialized view |
| 69 | // This view is maintained in PostHog and provides the same data as the complex query |
| 70 | // Explicitly select columns to avoid confusion from column order changes |
| 71 | const response = await posthogQuery( |
| 72 | 'sync-model-stats-internal', |
| 73 | ` |
| 74 | select mode, rank, model, tokens |
| 75 | from models_by_modes_last_7_days |
| 76 | limit 100000 |
| 77 | ` |
| 78 | ); |
| 79 | |
| 80 | if (response.status === 'error') { |
| 81 | console.error('[sync-internal-data] PostHog query failed:', response.error); |
| 82 | throw new Error(`PostHog query failed: ${JSON.stringify(response.error)}`); |
| 83 | } |
| 84 | |
| 85 | const results = (response.body.results ?? []) as ModeRankingRawResult[]; |
| 86 | console.log(`[sync-internal-data] Received ${results.length} results from PostHog`); |
| 87 | |
| 88 | console.log('[sync-internal-data] Sample results:', results.slice(0, 10)); |
| 89 | |
| 90 | // Group results by model |
| 91 | const modelRankings: ModelModeRankings = {}; |
| 92 | const modelTokens: ModelTokenCounts = {}; |
| 93 | const modesSeen = new Set<string>(); |
| 94 | for (const [mode, rank, model, tokens] of results) { |
| 95 | modesSeen.add(mode); |
| 96 | if (!modelRankings[model]) { |
| 97 | modelRankings[model] = {}; |
| 98 | } |
| 99 | modelRankings[model][mode as keyof ModeRankings] = rank; |
| 100 | |
| 101 | // Accumulate total tokens across all modes |
| 102 | modelTokens[model] = (modelTokens[model] || 0) + tokens; |
| 103 | } |
| 104 | |
| 105 | console.log('[sync-internal-data] Modes found in data:', Array.from(modesSeen)); |
| 106 | |
| 107 | console.log( |
| 108 | `[sync-internal-data] Processed rankings for ${Object.keys(modelRankings).length} unique models` |
| 109 | ); |
| 110 | |
| 111 | // Build the chart data updates object |
| 112 | const lastUpdated = new Date().toISOString(); |
| 113 | const chartDataUpdates: ModelChartDataUpdates = {}; |
| 114 | |
| 115 | for (const [normalizedModelName, rankings] of Object.entries(modelRankings)) { |
| 116 | chartDataUpdates[normalizedModelName] = { |
| 117 | modeRankings: { ...rankings, lastUpdated }, |
| 118 | last7DaysTokens: modelTokens[normalizedModelName] || 0, |
| 119 | }; |
| 120 | } |
| 121 | |
| 122 | return chartDataUpdates; |
no test coverage detected