(params: {
session: OpenCodeSessionRow;
messages: OpenCodeMessageRow[];
parts: OpenCodePartRow[];
now: Date;
provider: string;
modelId: string;
})
| 471 | } |
| 472 | |
| 473 | function buildPiEntries(params: { |
| 474 | session: OpenCodeSessionRow; |
| 475 | messages: OpenCodeMessageRow[]; |
| 476 | parts: OpenCodePartRow[]; |
| 477 | now: Date; |
| 478 | provider: string; |
| 479 | modelId: string; |
| 480 | }): BuildEntriesResult { |
| 481 | const sessionUuid = generateUuidV7(params.now); |
| 482 | const nowIso = params.now.toISOString(); |
| 483 | const entries: PiJson[] = [ |
| 484 | { |
| 485 | type: "session", |
| 486 | version: 3, |
| 487 | id: sessionUuid, |
| 488 | timestamp: nowIso, |
| 489 | cwd: params.session.directory ?? params.session.path ?? process.cwd(), |
| 490 | }, |
| 491 | { |
| 492 | type: "model_change", |
| 493 | id: shortId(), |
| 494 | parentId: null, |
| 495 | timestamp: nowIso, |
| 496 | provider: params.provider, |
| 497 | modelId: params.modelId, |
| 498 | }, |
| 499 | ]; |
| 500 | |
| 501 | // Migration boundary marker — appears as the first user message in |
| 502 | // the migrated session. This is intentionally stub usage (zeros) |
| 503 | // because no real LLM produced it; it's a synthetic marker only. |
| 504 | const boundary = makeMessageEntry( |
| 505 | "user", |
| 506 | `<!-- migrated from OpenCode session ${params.session.id} at ${nowIso} -->\n\nThe following conversation was migrated from a different harness. Reasoning context from prior turns may be incomplete; tool calls reference tools that may not exist in this environment.`, |
| 507 | nowIso, |
| 508 | null, |
| 509 | { |
| 510 | input: 0, |
| 511 | output: 0, |
| 512 | cacheRead: 0, |
| 513 | cacheWrite: 0, |
| 514 | totalTokens: 0, |
| 515 | cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }, |
| 516 | }, |
| 517 | ); |
| 518 | entries.push(boundary); |
| 519 | |
| 520 | const partsByMessage = new Map<string, OpenCodePartRow[]>(); |
| 521 | for (const part of params.parts) { |
| 522 | const list = partsByMessage.get(part.message_id) ?? []; |
| 523 | list.push(part); |
| 524 | partsByMessage.set(part.message_id, list); |
| 525 | } |
| 526 | |
| 527 | const messageIdToLastPiEntryId = new Map<string, string>(); |
| 528 | const orderedSourceMessageIds: string[] = []; |
| 529 | |
| 530 | let parentId = boundary.id as string; |
no test coverage detected