| 660 | } |
| 661 | |
| 662 | function handleStreamChunk({ |
| 663 | data, |
| 664 | state, |
| 665 | startTime, |
| 666 | logger, |
| 667 | userId, |
| 668 | agentId, |
| 669 | model, |
| 670 | }: { |
| 671 | data: Record<string, unknown> |
| 672 | state: StreamState |
| 673 | startTime: Date |
| 674 | logger: Logger |
| 675 | userId: string |
| 676 | agentId: string |
| 677 | model: string |
| 678 | }): StreamState { |
| 679 | const MAX_BUFFER_SIZE = 1 * 1024 * 1024 |
| 680 | |
| 681 | if ('error' in data) { |
| 682 | const errorData = data.error as Record<string, unknown> |
| 683 | logger.error( |
| 684 | { |
| 685 | userId, |
| 686 | agentId, |
| 687 | model, |
| 688 | errorCode: errorData?.code, |
| 689 | errorType: errorData?.type, |
| 690 | errorMessage: errorData?.message, |
| 691 | }, |
| 692 | 'Received error chunk in OpenCode Zen stream', |
| 693 | ) |
| 694 | return state |
| 695 | } |
| 696 | |
| 697 | const choices = data.choices as Array<Record<string, unknown>> | undefined |
| 698 | if (!choices?.length) { |
| 699 | return state |
| 700 | } |
| 701 | |
| 702 | const choice = choices[0] |
| 703 | const delta = choice.delta as Record<string, unknown> | undefined |
| 704 | const contentDelta = typeof delta?.content === 'string' ? delta.content : '' |
| 705 | |
| 706 | if (state.responseText.length < MAX_BUFFER_SIZE) { |
| 707 | state.responseText += contentDelta |
| 708 | if (state.responseText.length >= MAX_BUFFER_SIZE) { |
| 709 | state.responseText = |
| 710 | state.responseText.slice(0, MAX_BUFFER_SIZE) + '\n---[TRUNCATED]---' |
| 711 | logger.warn( |
| 712 | { userId, agentId, model }, |
| 713 | 'Response text buffer truncated at 1MB', |
| 714 | ) |
| 715 | } |
| 716 | } |
| 717 | |
| 718 | const reasoningDelta = |
| 719 | typeof delta?.reasoning_content === 'string' |