(path: string)
| 414 | * conversation's end. |
| 415 | */ |
| 416 | export async function loadMessagesFromJsonlPath(path: string): Promise<{ |
| 417 | messages: SerializedMessage[] |
| 418 | sessionId: UUID | undefined |
| 419 | }> { |
| 420 | const { messages: byUuid, leafUuids } = await loadTranscriptFile(path) |
| 421 | let tip: (typeof byUuid extends Map<UUID, infer T> ? T : never) | null = null |
| 422 | let tipTs = 0 |
| 423 | for (const m of byUuid.values()) { |
| 424 | if (m.isSidechain || !leafUuids.has(m.uuid)) continue |
| 425 | const ts = new Date(m.timestamp).getTime() |
| 426 | if (ts > tipTs) { |
| 427 | tipTs = ts |
| 428 | tip = m |
| 429 | } |
| 430 | } |
| 431 | if (!tip) return { messages: [], sessionId: undefined } |
| 432 | const chain = buildConversationChain(byUuid, tip) |
| 433 | return { |
| 434 | messages: removeExtraFields(chain), |
| 435 | // Leaf's sessionId — forked sessions copy chain[0] from the source |
| 436 | // transcript, so the root retains the source session's ID. Matches |
| 437 | // loadFullLog's mostRecentLeaf.sessionId. |
| 438 | sessionId: tip.sessionId as UUID | undefined, |
| 439 | } |
| 440 | } |
| 441 | |
| 442 | /** |
| 443 | * Loads a conversation for resume from various sources. |
no test coverage detected