* Build a list of messages to send to the model for summarization. * The full older portion of the conversation goes in as a "user" message * so the model produces a single text summary.
(toSummarize: Message[])
| 98 | export function isSummaryMessage(m: Message): boolean { |
| 99 | return m.role === 'system' && typeof m.content === 'string' && m.content.includes(SUMMARY_PREFIX); |
| 100 | } |
| 101 | |
| 102 | /** |
| 103 | * Build a list of messages to send to the model for summarization. |
| 104 | * The full older portion of the conversation goes in as a "user" message |
| 105 | * so the model produces a single text summary. |
| 106 | */ |
| 107 | function buildCompactionRequest(toSummarize: Message[]): Message[] { |
| 108 | // Render the messages into a single readable transcript |
| 109 | const lines: string[] = []; |
| 110 | for (const m of toSummarize) { |
| 111 | const role = m.role.toUpperCase(); |
| 112 | if (typeof m.content === 'string' && m.content.trim()) { |
| 113 | lines.push(`### ${role}\n${m.content}`); |
| 114 | } |
| 115 | if ('tool_calls' in m && Array.isArray((m as any).tool_calls)) { |
| 116 | for (const tc of (m as any).tool_calls) { |
| 117 | const fn = tc.function?.name ?? 'tool'; |
| 118 | const argsStr = typeof tc.function?.arguments === 'string' |
| 119 | ? tc.function.arguments |
| 120 | : JSON.stringify(tc.function?.arguments ?? {}); |
| 121 | lines.push(`### ${role} → tool call: ${fn}\n${argsStr.slice(0, 500)}`); |
| 122 | } |
| 123 | } |
| 124 | if (m.role === 'tool' && typeof m.content === 'string') { |
| 125 | lines.push(`### TOOL RESULT (${(m as any).name ?? '?'})\n${m.content.slice(0, 2000)}`); |
| 126 | } |
| 127 | } |
| 128 | return [ |