* Generates markdown summary from conversation log entries * This is the core shared logic between Claude and Copilot log parsers * * When a summaryTracker is provided, the function tracks the accumulated size * and stops rendering additional content when approaching the step summary lim
(logEntries, options)
| 102 | * @returns {{markdown: string, commandSummary: Array<string>, sizeLimitReached: boolean}} Generated markdown, command summary, and size limit status |
| 103 | */ |
| 104 | function generateConversationMarkdown(logEntries, options) { |
| 105 | const { formatToolCallback, formatInitCallback, summaryTracker } = options; |
| 106 | const renderEntries = normalizeEntriesForRendering(logEntries); |
| 107 | |
| 108 | const toolUsePairs = collectToolUsePairs(renderEntries); |
| 109 | |
| 110 | let markdown = ""; |
| 111 | let sizeLimitReached = false; |
| 112 | |
| 113 | function addContent(content) { |
| 114 | if (summaryTracker && !summaryTracker.add(content)) { |
| 115 | sizeLimitReached = true; |
| 116 | return false; |
| 117 | } |
| 118 | markdown += content; |
| 119 | return true; |
| 120 | } |
| 121 | |
| 122 | const initEntry = renderEntries.find(entry => entry.type === "system" && entry.subtype === "init"); |
| 123 | |
| 124 | if (initEntry && formatInitCallback) { |
| 125 | if (!addContent("## 🚀 Initialization\n\n")) { |
| 126 | return { markdown, commandSummary: [], sizeLimitReached }; |
| 127 | } |
| 128 | const initResult = formatInitCallback(initEntry); |
| 129 | if (typeof initResult === "string") { |
| 130 | if (!addContent(initResult)) { |
| 131 | return { markdown, commandSummary: [], sizeLimitReached }; |
| 132 | } |
| 133 | } else if (initResult && initResult.markdown) { |
| 134 | if (!addContent(initResult.markdown)) { |
| 135 | return { markdown, commandSummary: [], sizeLimitReached }; |
| 136 | } |
| 137 | } |
| 138 | if (!addContent("\n")) { |
| 139 | return { markdown, commandSummary: [], sizeLimitReached }; |
| 140 | } |
| 141 | } |
| 142 | |
| 143 | if (!addContent("\n## 🤖 Reasoning\n\n")) { |
| 144 | return { markdown, commandSummary: [], sizeLimitReached }; |
| 145 | } |
| 146 | |
| 147 | for (const entry of renderEntries) { |
| 148 | if (sizeLimitReached) break; |
| 149 | |
| 150 | if (entry.type === "assistant" && entry.message?.content) { |
| 151 | for (const content of entry.message.content) { |
| 152 | if (sizeLimitReached) break; |
| 153 | |
| 154 | if (content.type === "text" && content.text) { |
| 155 | let text = content.text.trim(); |
| 156 | text = unfenceMarkdown(text); |
| 157 | if (text && text.length > 0) { |
| 158 | if (!addContent(text + "\n\n")) { |
| 159 | break; |
| 160 | } |
| 161 | } |
no test coverage detected