(
messages: Array<{ user?: string; text?: string }>,
botUserId: string
)
| 10 | * or when human messages are already long-form. |
| 11 | */ |
| 12 | export function buildThreadStyleHint( |
| 13 | messages: Array<{ user?: string; text?: string }>, |
| 14 | botUserId: string |
| 15 | ): string | null { |
| 16 | const humanMessages = messages |
| 17 | .filter(msg => msg.user && msg.user !== botUserId && msg.text) |
| 18 | .map(msg => msg.text!.trim()) |
| 19 | .filter(text => text.length > 0); |
| 20 | |
| 21 | if (humanMessages.length < 1) return null; |
| 22 | |
| 23 | // Measure median character length of human messages (true median for even counts) |
| 24 | const lengths = humanMessages.map(t => t.length).sort((a, b) => a - b); |
| 25 | const mid = Math.floor(lengths.length / 2); |
| 26 | const median = lengths.length % 2 === 0 |
| 27 | ? (lengths[mid - 1] + lengths[mid]) / 2 |
| 28 | : lengths[mid]; |
| 29 | |
| 30 | // If humans are writing short messages (under ~400 chars ≈ 3-4 sentences), |
| 31 | // tell Addie to be concise. Over 400 is long-form enough that Addie's |
| 32 | // normal style is fine. |
| 33 | if (median > 400) return null; |
| 34 | |
| 35 | return [ |
| 36 | '## Response Style — Thread Calibration', |
| 37 | `Humans in this thread are averaging ~${Math.round(median)}-character replies. Keep yours proportional.`, |
| 38 | 'Your baseline conciseness rules apply with extra force here — lead with the answer, not background.', |
| 39 | ].join('\n'); |
| 40 | } |
| 41 | |
| 42 | /** |
| 43 | * Check if a thread has multiple human participants. |
no test coverage detected