| 880 | } |
| 881 | |
| 882 | func appendNormalizedStreamContent( |
| 883 | content []normalizedContentPart, |
| 884 | part fantasy.StreamPart, |
| 885 | streamDebugBytes *int, |
| 886 | ) []normalizedContentPart { |
| 887 | switch part.Type { |
| 888 | case fantasy.StreamPartTypeTextDelta: |
| 889 | return appendStreamContentText(content, "text", part.Delta, streamDebugBytes) |
| 890 | case fantasy.StreamPartTypeReasoningStart, fantasy.StreamPartTypeReasoningDelta: |
| 891 | return appendStreamContentText(content, "reasoning", part.Delta, streamDebugBytes) |
| 892 | case fantasy.StreamPartTypeToolInputStart, |
| 893 | fantasy.StreamPartTypeToolInputDelta, |
| 894 | fantasy.StreamPartTypeToolInputEnd: |
| 895 | // Incremental tool input parts are emitted before the final |
| 896 | // tool_call summary. Attribute each chunk to its tool call |
| 897 | // so interrupted streams can reconstruct which partial input |
| 898 | // belonged to which invocation. |
| 899 | return appendStreamToolInput(content, part, streamDebugBytes) |
| 900 | case fantasy.StreamPartTypeToolCall: |
| 901 | return append(content, normalizedContentPart{ |
| 902 | Type: canonicalContentType(string(part.Type)), |
| 903 | ToolCallID: part.ID, |
| 904 | ToolName: part.ToolCallName, |
| 905 | Arguments: boundText(part.ToolCallInput), |
| 906 | InputLength: utf8.RuneCountInString(part.ToolCallInput), |
| 907 | }) |
| 908 | case fantasy.StreamPartTypeToolResult: |
| 909 | return append(content, normalizedContentPart{ |
| 910 | Type: canonicalContentType(string(part.Type)), |
| 911 | ToolCallID: part.ID, |
| 912 | ToolName: part.ToolCallName, |
| 913 | Result: boundText(part.ToolCallInput), |
| 914 | }) |
| 915 | case fantasy.StreamPartTypeSource: |
| 916 | return append(content, normalizedContentPart{ |
| 917 | Type: string(part.Type), |
| 918 | SourceType: string(part.SourceType), |
| 919 | Title: part.Title, |
| 920 | URL: part.URL, |
| 921 | }) |
| 922 | default: |
| 923 | return content |
| 924 | } |
| 925 | } |
| 926 | |
| 927 | func normalizeToolResultOutput(output fantasy.ToolResultOutputContent) string { |
| 928 | switch v := output.(type) { |