Repository: microsoft/semantic-kernel
File: dotnet/samples/Concepts/Filtering/RetryWithFilters.cs (C#)

Code before:
        }

        private async IAsyncEnumerable<StreamingKernelContent> DeferredStreamingRetryResult(IAsyncEnumerable<StreamingKernelContent> results, FunctionInvocationContext context, Func<FunctionInvocationContext, Task> retry)
        {
            // I need to manually enumerate the results to catch the exception.
            var enumerator = results.GetAsyncEnumerator();

            while (true)
            {
                try
                {
                    if (!await enumerator.MoveNextAsync())
                    {
                        break;
                    }
                }
                catch (ClientResultException exception) when (exception.Status == (int)HttpStatusCode.Unauthorized)
                {
                    // If any exception is thrown, get current execution settings to override settings with fallback model id
                    PromptExecutionSettings executionSettings = context.Arguments.ExecutionSettings![PromptExecutionSettings.DefaultServiceId];

                    // Override settings with fallback model id
                    executionSettings.ModelId = fallbackModelId;

                    // Try to invoke function again
                    await retry(context);

                    // Set the new result enumerator
                    enumerator = context.Result.GetValue<IAsyncEnumerable<StreamingKernelContent>>()!.GetAsyncEnumerator();

                    // Retry the enumeration
                    continue;
                }

                yield return enumerator.Current;
            }
        }
    }
}


Review comment (suggestion):
Will this change the execution settings that the user passed in permanently?  E.g. if they invoked again after the first invoke with the same execution settings object, would it have been changed to use the fallbackModelId or is the execution settings cloned somewhere?  If this changes the source, we may need to clone here, to avoid showing a pattern with this issue.

Code after:
        }

        private async IAsyncEnumerable<StreamingKernelContent> DeferredStreamingRetryResult(IAsyncEnumerable<StreamingKernelContent> results, FunctionInvocationContext context, Func<FunctionInvocationContext, Task> retry)
        {
            // I need to manually enumerate the results to catch the exception.
            var enumerator = results.GetAsyncEnumerator();

            while (true)
            {
                try
                {
                    if (!await enumerator.MoveNextAsync())
                    {
                        break;
                    }
                }
                catch (ClientResultException exception) when (exception.Status == (int)HttpStatusCode.Unauthorized)
                {
                    // In a scenario where the streaming already started and it was interrupted by an exception,
                    // would be advisable some extra logic to handle any update necessary in the caller side before the retrial starts

                    // If any exception is thrown, get current execution settings to override settings with fallback model id
                    PromptExecutionSettings executionSettings = context.Arguments.ExecutionSettings![PromptExecutionSettings.DefaultServiceId];

                    // Override settings with fallback model id
                    executionSettings.ModelId = fallbackModelId;

                    // Try to invoke function again
                    await retry(context);

                    // Set the new result enumerator
                    enumerator = context.Result.GetValue<IAsyncEnumerable<StreamingKernelContent>>()!.GetAsyncEnumerator();

                    // Retry the enumeration
                    continue;
                }

                yield return enumerator.Current;
            }
        }
    }
}