This Q/A from the UX SE covers dynamic text legibility & asserts "gray-scale contrast is more important than color contrast" & ensures compliance with WCAG accessibility requirements. It uses a luminosity formula to evaluate the background color & picks black text for light colors & white text for dark.
I think your problem could be solved in a similar manner: given a foreground text color, determine its luminosity & generate background colors that have sufficient contrast. Extending this to colored text is a bit more complex as there are more dimensions to your input variable (the foreground color). To make the problem more manageable, I would try restricting the backgrounds to tints, tones & shades of the foreground as follows:
- Determine the luminosity of the foreground color you wish to use
- If it is less than or equal to 0.18 use a light tint or a light tone of the foreground color as the background (by adding white or a light grey respectively)
- If it is less than or equal to 0.18 use a dark shade or a dark tone of the foreground color as the background (by adding black or a dark grey respectively)
If this restricts your palette too much or makes things too samey, you could try something like this:
- Generate your procedural color set
- Determine the luminosity values of the color set, among them:
- Call the color with the lightest luminosity color_L
- Call the color with the lightest luminosity color_D
- Determine the luminosity of the foreground color you wish to use
- If the foreground luminosity is less than or equal to 0.18 use a light tint or a light tone of the color_L as the background
- If the foreground luminosity is less than or equal to 0.18 use a dark shade or a dark tone of the color_D as the background