(input: { userFacts: string[]; episodes: { prompt: string; files?: string[] }[] })
| 50 | } |
| 51 | |
| 52 | export function buildUserModel(input: { userFacts: string[]; episodes: { prompt: string; files?: string[] }[] }): UserModel { |
| 53 | const preferences = input.userFacts |
| 54 | .map(f => f.replace(/!important\b/gi, '').replace(/^\s*[\-*]\s*/, '').replace(/\s+/g, ' ').trim()) |
| 55 | .filter(Boolean); |
| 56 | const recentThemes = extractThemes(input.episodes.map(e => e.prompt)); |
| 57 | const areas = favoriteAreas(input.episodes.map(e => e.files ?? [])); |
| 58 | const bits: string[] = []; |
| 59 | if (preferences.length) bits.push(`${preferences.length} stated preference${preferences.length === 1 ? '' : 's'}`); |
| 60 | if (recentThemes.length) bits.push(`recent focus: ${recentThemes.slice(0, 3).join(', ')}`); |
| 61 | if (areas.length) bits.push(`works mostly in ${areas[0]}`); |
| 62 | return { |
| 63 | preferences, |
| 64 | recentThemes, |
| 65 | favoriteAreas: areas, |
| 66 | taskCount: input.episodes.length, |
| 67 | summary: bits.length ? bits.join(' · ') : 'Nothing learned about you yet.', |
| 68 | }; |
| 69 | } |
| 70 | |
| 71 | /** A readable block for `qodex whoami` / the dashboard. PURE. */ |
| 72 | export function renderUserModel(m: UserModel): string { |
no test coverage detected