|
78 | 78 | let fmSession = FoundationModels.LanguageModelSession( |
79 | 79 | model: systemModel, |
80 | 80 | tools: session.tools.toFoundationModels(), |
81 | | - instructions: session.instructions?.toFoundationModels() |
| 81 | + transcript: session.transcript.toFoundationModels(instructions: session.instructions) |
82 | 82 | ) |
83 | 83 |
|
84 | 84 | let fmResponse = try await fmSession.respond(to: fmPrompt, options: fmOptions) |
|
115 | 115 | let fmSession = FoundationModels.LanguageModelSession( |
116 | 116 | model: systemModel, |
117 | 117 | tools: session.tools.toFoundationModels(), |
118 | | - instructions: session.instructions?.toFoundationModels() |
| 118 | + transcript: session.transcript.toFoundationModels(instructions: session.instructions) |
119 | 119 | ) |
120 | 120 |
|
121 | 121 | let stream = AsyncThrowingStream<LanguageModelSession.ResponseStream<Content>.Snapshot, any Error> { |
|
475 | 475 | nil |
476 | 476 | } |
477 | 477 | } |
| 478 | + |
| 479 | + @available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, visionOS 26.0, *) |
| 480 | + extension Transcript { |
| 481 | + fileprivate func toFoundationModels(instructions: AnyLanguageModel.Instructions?) -> FoundationModels.Transcript |
| 482 | + { |
| 483 | + var fmEntries: [FoundationModels.Transcript.Entry] = [] |
| 484 | + |
| 485 | + // Add instructions entry if provided and not already in transcript |
| 486 | + if let instructions = instructions { |
| 487 | + let hasInstructions = |
| 488 | + self.first.map { entry in |
| 489 | + if case .instructions = entry { return true } else { return false } |
| 490 | + } ?? false |
| 491 | + |
| 492 | + if !hasInstructions { |
| 493 | + let fmInstructions = FoundationModels.Transcript.Instructions( |
| 494 | + segments: [.text(.init(content: instructions.description))], |
| 495 | + toolDefinitions: [] |
| 496 | + ) |
| 497 | + fmEntries.append(.instructions(fmInstructions)) |
| 498 | + } |
| 499 | + } |
| 500 | + |
| 501 | + // Convert each entry |
| 502 | + for entry in self { |
| 503 | + switch entry { |
| 504 | + case .instructions(let instr): |
| 505 | + let textContent = instr.segments.compactMap { segment -> String? in |
| 506 | + if case .text(let textSegment) = segment { |
| 507 | + return textSegment.content |
| 508 | + } |
| 509 | + return nil |
| 510 | + }.joined(separator: " ") |
| 511 | + let fmInstructions = FoundationModels.Transcript.Instructions( |
| 512 | + segments: [.text(.init(content: textContent))], |
| 513 | + toolDefinitions: [] |
| 514 | + ) |
| 515 | + fmEntries.append(.instructions(fmInstructions)) |
| 516 | + |
| 517 | + case .prompt(let prompt): |
| 518 | + let textContent = prompt.segments.compactMap { segment -> String? in |
| 519 | + if case .text(let textSegment) = segment { |
| 520 | + return textSegment.content |
| 521 | + } |
| 522 | + return nil |
| 523 | + }.joined(separator: " ") |
| 524 | + let fmPrompt = FoundationModels.Transcript.Prompt( |
| 525 | + segments: [.text(.init(content: textContent))] |
| 526 | + ) |
| 527 | + fmEntries.append(.prompt(fmPrompt)) |
| 528 | + |
| 529 | + case .response(let response): |
| 530 | + let textContent = response.segments.compactMap { segment -> String? in |
| 531 | + if case .text(let textSegment) = segment { |
| 532 | + return textSegment.content |
| 533 | + } |
| 534 | + return nil |
| 535 | + }.joined(separator: " ") |
| 536 | + let fmResponse = FoundationModels.Transcript.Response( |
| 537 | + assetIDs: [], |
| 538 | + segments: [.text(.init(content: textContent))] |
| 539 | + ) |
| 540 | + fmEntries.append(.response(fmResponse)) |
| 541 | + |
| 542 | + case .toolCalls, .toolOutput: |
| 543 | + // Tool calls/outputs require more complex conversion; skip for now |
| 544 | + break |
| 545 | + } |
| 546 | + } |
| 547 | + |
| 548 | + return FoundationModels.Transcript(entries: fmEntries) |
| 549 | + } |
| 550 | + } |
478 | 551 | #endif |
0 commit comments