refactor: move container bias handling into subflows
This commit is contained in:
parent
47dc3b3c3b
commit
c2ae39f292
|
|
@ -39,8 +39,6 @@ public class Container<T extends ContainerType> implements FlowNode {
|
|||
|
||||
List<IODescriptor> outputs;
|
||||
|
||||
List<BlockBiasAnnotation> biasAnnotations = List.of();
|
||||
|
||||
String laneId;
|
||||
|
||||
ContainerConfiguration<T> specificConfiguration;
|
||||
|
|
@ -61,21 +59,27 @@ public class Container<T extends ContainerType> implements FlowNode {
|
|||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Containers are not bias-annotatable: bias annotations live only on the
|
||||
* nodes of the inner subflow and are activated via {@code includeSubflow}
|
||||
* on a bias rerun. Always returns an empty list.
|
||||
*/
|
||||
@Override
|
||||
@JsonIgnore
|
||||
public List<BlockBiasAnnotation> getBiasAnnotations() {
|
||||
return biasAnnotations == null ? List.of() : biasAnnotations;
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Builder
|
||||
public Container(@NonNull ContainerConfiguration<T> specificConfiguration, @Singular List<IODescriptor> inputs,
|
||||
@Singular List<IODescriptor> outputs,
|
||||
@Singular("biasAnnotation") List<BlockBiasAnnotation> biasAnnotations, T type,
|
||||
T type,
|
||||
@JsonProperty("typeName") @JsonAlias("type") String resolvedTypeName,
|
||||
Position position, String laneId) {
|
||||
this.specificConfiguration = specificConfiguration;
|
||||
this.name = specificConfiguration.getName();
|
||||
this.inputs = inputs;
|
||||
this.outputs = outputs;
|
||||
this.biasAnnotations = biasAnnotations == null ? List.of() : List.copyOf(biasAnnotations);
|
||||
this.typeName = type != null ? type.getName() : resolvedTypeName;
|
||||
this.position = position;
|
||||
this.type = type != null ? type : resolveContainerType(this.typeName);
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ public class BiasAnnotationsController {
|
|||
public record BiasAnnotationDescriptor(
|
||||
String type,
|
||||
String blockProperty,
|
||||
String containerProperty,
|
||||
boolean multiple,
|
||||
int maxItems,
|
||||
JsonNode schema,
|
||||
|
|
@ -61,7 +60,6 @@ public class BiasAnnotationsController {
|
|||
return new BiasAnnotationDescriptor(
|
||||
BlockBiasAnnotation.class.getSimpleName(),
|
||||
"biasAnnotations",
|
||||
"biasAnnotations",
|
||||
true,
|
||||
BlockBiasAnnotation.MAX_PER_BLOCK,
|
||||
schemaProducer.generateSchemaNode(BlockBiasAnnotation.class),
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ public class ContainerBiasCapabilitiesController {
|
|||
boolean fullFlowExperimentSupported,
|
||||
boolean externalSideEffects,
|
||||
boolean configurationDependent,
|
||||
boolean subflowPropagationSupported,
|
||||
List<BiasActivationMode> activationModes) {
|
||||
}
|
||||
|
||||
|
|
@ -69,14 +70,19 @@ public class ContainerBiasCapabilitiesController {
|
|||
}
|
||||
|
||||
private ContainerBiasCapabilityDescriptor descriptor(Container<?> container) {
|
||||
// Containers are not bias-annotatable at their boundary: they carry no
|
||||
// activation modes of their own. They still participate in a full-flow
|
||||
// bias rerun via subflow propagation (includeSubflow), which activates
|
||||
// the executable annotations on their inner subflow nodes.
|
||||
List<BiasActivationMode> modes = adapterRegistry.supportedModes(container).stream().sorted().toList();
|
||||
return new ContainerBiasCapabilityDescriptor(
|
||||
container.getType().getName(),
|
||||
!modes.isEmpty(),
|
||||
true,
|
||||
false,
|
||||
!modes.isEmpty(),
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
modes);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import java.util.Set;
|
|||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import it.cnr.isti.workflow.manager.blocks.Block;
|
||||
import it.cnr.isti.workflow.manager.executions.steps.Input;
|
||||
import it.cnr.isti.workflow.manager.flows.model.FlowNode;
|
||||
import it.cnr.isti.workflow.manager.flows.model.bias.BiasActivationMode;
|
||||
|
|
@ -17,7 +18,7 @@ public class InputBiasBehaviorAdapter implements BiasBehaviorAdapter {
|
|||
|
||||
@Override
|
||||
public boolean supports(FlowNode node, BiasActivationMode mode) {
|
||||
return mode == BiasActivationMode.INPUT_TRANSFORMATION;
|
||||
return mode == BiasActivationMode.INPUT_TRANSFORMATION && node instanceof Block<?>;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -37,6 +38,6 @@ public class InputBiasBehaviorAdapter implements BiasBehaviorAdapter {
|
|||
|
||||
@Override
|
||||
public Set<BiasActivationMode> supportedModes(FlowNode node) {
|
||||
return Set.of(BiasActivationMode.INPUT_TRANSFORMATION);
|
||||
return node instanceof Block<?> ? Set.of(BiasActivationMode.INPUT_TRANSFORMATION) : Set.of();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import java.util.Set;
|
|||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import it.cnr.isti.workflow.manager.blocks.Block;
|
||||
import it.cnr.isti.workflow.manager.flows.model.FlowNode;
|
||||
import it.cnr.isti.workflow.manager.flows.model.bias.BiasActivationMode;
|
||||
import it.cnr.isti.workflow.manager.flows.model.bias.BlockBiasAnnotation;
|
||||
|
|
@ -13,7 +14,7 @@ public class OutputBiasBehaviorAdapter implements BiasBehaviorAdapter {
|
|||
|
||||
@Override
|
||||
public boolean supports(FlowNode node, BiasActivationMode mode) {
|
||||
return mode == BiasActivationMode.OUTPUT_TRANSFORMATION;
|
||||
return mode == BiasActivationMode.OUTPUT_TRANSFORMATION && node instanceof Block<?>;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -23,6 +24,6 @@ public class OutputBiasBehaviorAdapter implements BiasBehaviorAdapter {
|
|||
|
||||
@Override
|
||||
public Set<BiasActivationMode> supportedModes(FlowNode node) {
|
||||
return Set.of(BiasActivationMode.OUTPUT_TRANSFORMATION);
|
||||
return node instanceof Block<?> ? Set.of(BiasActivationMode.OUTPUT_TRANSFORMATION) : Set.of();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ public record NodeTypeCapabilities(
|
|||
}
|
||||
|
||||
public static NodeTypeCapabilities container() {
|
||||
return new NodeTypeCapabilities(NodeVisualRole.CONTAINER, false, true, true, true, true, true);
|
||||
// biasAnnotationsAllowed = false: containers are not bias-annotatable;
|
||||
// bias lives only on the inner subflow nodes (activated via includeSubflow).
|
||||
return new NodeTypeCapabilities(NodeVisualRole.CONTAINER, false, false, true, true, true, true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,6 @@ import it.cnr.isti.workflow.manager.containers.types.GenericContainerType;
|
|||
import it.cnr.isti.workflow.manager.controllers.BiasAnnotationsController.BiasAnnotationDescriptor;
|
||||
import it.cnr.isti.workflow.manager.flows.model.bias.BiasAnnotationSource;
|
||||
import it.cnr.isti.workflow.manager.flows.model.bias.BiasAnnotationStatus;
|
||||
import it.cnr.isti.workflow.manager.flows.model.bias.BiasActivationMode;
|
||||
import it.cnr.isti.workflow.manager.flows.model.bias.BiasBehavioralProbe;
|
||||
import it.cnr.isti.workflow.manager.flows.model.bias.BiasCategory;
|
||||
import it.cnr.isti.workflow.manager.flows.model.bias.BiasSeverity;
|
||||
import it.cnr.isti.workflow.manager.flows.model.bias.BlockBiasAnnotation;
|
||||
|
|
@ -50,9 +48,6 @@ class BiasAnnotationsControllerTest {
|
|||
@Autowired
|
||||
GenericContainerFactory genericContainerFactory;
|
||||
|
||||
@Autowired
|
||||
GenericContainerType genericContainerType;
|
||||
|
||||
@Autowired
|
||||
FlowService flowService;
|
||||
|
||||
|
|
@ -62,7 +57,6 @@ class BiasAnnotationsControllerTest {
|
|||
|
||||
assertEquals(BlockBiasAnnotation.class.getSimpleName(), descriptor.type());
|
||||
assertEquals("biasAnnotations", descriptor.blockProperty());
|
||||
assertEquals("biasAnnotations", descriptor.containerProperty());
|
||||
assertTrue(descriptor.multiple());
|
||||
assertEquals(BlockBiasAnnotation.MAX_PER_BLOCK, descriptor.maxItems());
|
||||
assertEquals("PROPOSED", descriptor.defaults().get("status"));
|
||||
|
|
@ -138,27 +132,24 @@ class BiasAnnotationsControllerTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
void biasAnnotationRoundTripsWithContainerJson() throws Exception {
|
||||
BlockBiasAnnotation annotation = new BlockBiasAnnotation(
|
||||
null,
|
||||
BiasCategory.SELECTION_BIAS,
|
||||
BiasSeverity.HIGH,
|
||||
"The subflow may discard relevant candidates.",
|
||||
null,
|
||||
"Review the subflow boundary inputs and outputs.",
|
||||
BiasAnnotationStatus.CONFIRMED,
|
||||
BiasAnnotationSource.MANUAL,
|
||||
null,
|
||||
new BiasBehavioralProbe(BiasActivationMode.INPUT_TRANSFORMATION,
|
||||
"biased:${original}", java.util.List.of(), "Boundary input changes"));
|
||||
Container<GenericContainerType> container = annotatedContainer(annotation);
|
||||
void containerDropsBiasAnnotationsFromJson() throws Exception {
|
||||
// Containers are not bias-annotatable: any biasAnnotations present in
|
||||
// incoming JSON must be ignored, and getBiasAnnotations() stays empty.
|
||||
Container<GenericContainerType> container = genericContainerFactory.create(
|
||||
GenericContainerConfiguration.builder().name("Container")
|
||||
.subFlow(FlowData.builder().build()).build());
|
||||
ObjectNode json = ObjectMapperHolder.mapper.valueToTree(container);
|
||||
assertFalse(json.has("biasAnnotations"));
|
||||
var annotations = json.putArray("biasAnnotations");
|
||||
ObjectNode annotationNode = annotations.addObject();
|
||||
annotationNode.put("category", BiasCategory.SELECTION_BIAS.name());
|
||||
annotationNode.put("severity", BiasSeverity.HIGH.name());
|
||||
annotationNode.put("issue", "Should be ignored on a container.");
|
||||
|
||||
String json = ObjectMapperHolder.mapper.writeValueAsString(container);
|
||||
Container<?> restored = ObjectMapperHolder.mapper.readValue(json, Container.class);
|
||||
Container<?> restored = ObjectMapperHolder.mapper.treeToValue(json, Container.class);
|
||||
|
||||
assertEquals(1, restored.getBiasAnnotations().size());
|
||||
assertEquals(BiasCategory.SELECTION_BIAS, restored.getBiasAnnotations().getFirst().category());
|
||||
assertEquals(annotation.id(), restored.getBiasAnnotations().getFirst().id());
|
||||
assertNotNull(restored.getBiasAnnotations());
|
||||
assertTrue(restored.getBiasAnnotations().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -226,57 +217,6 @@ class BiasAnnotationsControllerTest {
|
|||
assertTrue(exception.getMessage().contains("BIAS_CATEGORY_REQUIRED"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void annotatedContainerIsValidatedAndPersistedInsideFlowJson() {
|
||||
BlockBiasAnnotation annotation = new BlockBiasAnnotation(
|
||||
null,
|
||||
BiasCategory.TRANSPARENCY_RISK,
|
||||
BiasSeverity.MEDIUM,
|
||||
"The nested process is opaque.",
|
||||
null,
|
||||
"Expose the nested process rationale.",
|
||||
BiasAnnotationStatus.MITIGATED,
|
||||
BiasAnnotationSource.MANUAL,
|
||||
null,
|
||||
null);
|
||||
FlowCreateRequest request = new FlowCreateRequest(
|
||||
"Container bias persistence test",
|
||||
"Flow with a container bias annotation",
|
||||
FlowData.builder().container(annotatedContainer(annotation)).build());
|
||||
|
||||
FlowView created = flowService.createFlow("bias-container-test-user", request);
|
||||
FlowView restored = flowService.getFlow(created.id(), "bias-container-test-user");
|
||||
|
||||
assertEquals(1, restored.flow().getContainers().getFirst().getBiasAnnotations().size());
|
||||
assertEquals(BiasCategory.TRANSPARENCY_RISK,
|
||||
restored.flow().getContainers().getFirst().getBiasAnnotations().getFirst().category());
|
||||
}
|
||||
|
||||
@Test
|
||||
void flowValidationRejectsUnsupportedContainerProbe() {
|
||||
BlockBiasAnnotation annotation = new BlockBiasAnnotation(
|
||||
null,
|
||||
BiasCategory.AUTOMATION_BIAS,
|
||||
BiasSeverity.MEDIUM,
|
||||
"Invalid prompt probe on a container.",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
new BiasBehavioralProbe(BiasActivationMode.PROMPT_DIRECTIVE,
|
||||
"Prefer the initial assumption", java.util.List.of(), null));
|
||||
FlowCreateRequest request = new FlowCreateRequest(
|
||||
"Invalid container probe test",
|
||||
null,
|
||||
FlowData.builder().container(annotatedContainer(annotation)).build());
|
||||
|
||||
RuntimeException exception = assertThrows(RuntimeException.class,
|
||||
() -> flowService.createFlow("bias-container-test-user", request));
|
||||
|
||||
assertTrue(exception.getMessage().contains("BIAS_PROBE_MODE_UNSUPPORTED"));
|
||||
assertTrue(exception.getMessage().contains("container"));
|
||||
}
|
||||
|
||||
private Block<LLMBlockType> annotatedBlock(BlockBiasAnnotation annotation) {
|
||||
LLMBlockConfiguration configuration = LLMBlockConfiguration.builder()
|
||||
|
|
@ -294,19 +234,4 @@ class BiasAnnotationsControllerTest {
|
|||
.build();
|
||||
}
|
||||
|
||||
private Container<GenericContainerType> annotatedContainer(BlockBiasAnnotation annotation) {
|
||||
GenericContainerConfiguration configuration = GenericContainerConfiguration.builder()
|
||||
.name("Annotated container")
|
||||
.subFlow(FlowData.builder().build())
|
||||
.build();
|
||||
Container<GenericContainerType> canonical = genericContainerFactory.create(configuration);
|
||||
return Container.<GenericContainerType>builder()
|
||||
.specificConfiguration(configuration)
|
||||
.inputs(canonical.getInputs())
|
||||
.outputs(canonical.getOutputs())
|
||||
.type(genericContainerType)
|
||||
.position(canonical.getPosition())
|
||||
.biasAnnotation(annotation)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,9 +37,6 @@ import it.cnr.isti.workflow.manager.executions.ExecutionObject;
|
|||
import it.cnr.isti.workflow.manager.executions.ExecutionStatus;
|
||||
import it.cnr.isti.workflow.manager.executions.ExecutionsService;
|
||||
import it.cnr.isti.workflow.manager.executions.executors.NodeExecutors;
|
||||
import it.cnr.isti.workflow.manager.executions.bias.runtime.BiasBehaviorAdapterRegistry;
|
||||
import it.cnr.isti.workflow.manager.executions.bias.runtime.BiasPreparedExecution;
|
||||
import it.cnr.isti.workflow.manager.executions.steps.Input;
|
||||
import it.cnr.isti.workflow.manager.flows.model.FlowData;
|
||||
import it.cnr.isti.workflow.manager.flows.model.bias.BiasActivationMode;
|
||||
import it.cnr.isti.workflow.manager.flows.model.bias.BiasAnnotationSource;
|
||||
|
|
@ -51,8 +48,6 @@ import it.cnr.isti.workflow.manager.flows.model.bias.BlockBiasAnnotation;
|
|||
import it.cnr.isti.workflow.manager.llms.LLMDescriptor;
|
||||
import it.cnr.isti.workflow.manager.llms.providers.LLMProvider;
|
||||
import it.cnr.isti.workflow.manager.flows.validation.ValidationErrorCode;
|
||||
import it.cnr.isti.workflow.manager.ios.IODescriptor;
|
||||
import it.cnr.isti.workflow.manager.ios.IOType;
|
||||
|
||||
@SpringBootTest
|
||||
@TestPropertySource(locations = "classpath:test.properties")
|
||||
|
|
@ -116,9 +111,6 @@ class BiasExperimentsIntegrationTest {
|
|||
@Autowired
|
||||
ContainerBiasCapabilitiesController containerCapabilitiesController;
|
||||
|
||||
@Autowired
|
||||
GenericContainerType genericContainerType;
|
||||
|
||||
@Autowired
|
||||
GenericContainerFactory genericContainerFactory;
|
||||
|
||||
|
|
@ -156,100 +148,10 @@ class BiasExperimentsIntegrationTest {
|
|||
assertTrue(containerCapabilities.supported());
|
||||
assertFalse(containerCapabilities.isolatedExperimentSupported());
|
||||
assertTrue(containerCapabilities.fullFlowExperimentSupported());
|
||||
assertEquals(List.of(BiasActivationMode.INPUT_TRANSFORMATION, BiasActivationMode.OUTPUT_TRANSFORMATION),
|
||||
containerCapabilities.activationModes());
|
||||
}
|
||||
|
||||
@Test
|
||||
void containerBoundaryAppliesInputAndOutputTransformations() {
|
||||
BlockBiasAnnotation inputAnnotation = annotation(
|
||||
"container-input-bias",
|
||||
new BiasBehavioralProbe(BiasActivationMode.INPUT_TRANSFORMATION,
|
||||
"input:${original}", List.of("payload"), "Input is transformed"));
|
||||
BlockBiasAnnotation outputAnnotation = annotation(
|
||||
"container-output-bias",
|
||||
new BiasBehavioralProbe(BiasActivationMode.OUTPUT_TRANSFORMATION,
|
||||
"output:${original}", List.of(), "Output is transformed"));
|
||||
Container<GenericContainerType> container = Container.<GenericContainerType>builder()
|
||||
.specificConfiguration(GenericContainerConfiguration.builder()
|
||||
.name("Biased boundary")
|
||||
.subFlow(FlowData.builder().build())
|
||||
.build())
|
||||
.input(IODescriptor.of("payload", IOType.TEXT))
|
||||
.output(IODescriptor.of("result", IOType.TEXT))
|
||||
.type(genericContainerType)
|
||||
.biasAnnotation(inputAnnotation)
|
||||
.biasAnnotation(outputAnnotation)
|
||||
.build();
|
||||
BiasExecutionContext context = new BiasExecutionContext(
|
||||
"container-experiment",
|
||||
BiasExecutionMode.BIAS_VARIANT,
|
||||
Map.of(container.getId(), List.of(inputAnnotation.id(), outputAnnotation.id())),
|
||||
ExternalSideEffectPolicy.BLOCK,
|
||||
false);
|
||||
|
||||
BiasPreparedExecution prepared = BiasBehaviorAdapterRegistry.prepare(
|
||||
container,
|
||||
List.of(Input.detached(container.getInputs().getFirst(), "candidate")),
|
||||
Map.of(),
|
||||
context,
|
||||
null);
|
||||
Map<String, Object> completed = BiasBehaviorAdapterRegistry.complete(prepared, Map.of("result", "accepted"));
|
||||
|
||||
assertEquals("input:candidate", prepared.getInputs().getFirst().getValue());
|
||||
assertEquals("output:accepted", completed.get("result"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void fullFlowBiasRerunActivatesContainerAnnotation() {
|
||||
BlockBiasAnnotation annotation = annotation(
|
||||
"container-full-flow-bias",
|
||||
new BiasBehavioralProbe(BiasActivationMode.OUTPUT_TRANSFORMATION,
|
||||
"container:${original}", List.of(), "Container output is transformed"));
|
||||
LLMBlockConfiguration innerConfiguration = LLMBlockConfiguration.builder()
|
||||
.name("Inner decision")
|
||||
.prompt("Return a decision")
|
||||
.llmDescriptor(LLMDescriptor.builder()
|
||||
.provider("biasExperimentProvider")
|
||||
.model("bias-test-model")
|
||||
.build())
|
||||
.build();
|
||||
Block<LLMBlockType> innerBlock = llmBlockFactory.create(innerConfiguration);
|
||||
GenericContainerConfiguration containerConfiguration = GenericContainerConfiguration.builder()
|
||||
.name("Annotated process")
|
||||
.subFlow(FlowData.builder().block(innerBlock).build())
|
||||
.build();
|
||||
Container<GenericContainerType> canonical = genericContainerFactory.create(containerConfiguration);
|
||||
Container<GenericContainerType> container = Container.<GenericContainerType>builder()
|
||||
.specificConfiguration(containerConfiguration)
|
||||
.inputs(canonical.getInputs())
|
||||
.outputs(canonical.getOutputs())
|
||||
.type(genericContainerType)
|
||||
.biasAnnotation(annotation)
|
||||
.build();
|
||||
ExecutionObject baseline = executionsService.createExecutionForFlow(
|
||||
"container-bias-flow",
|
||||
"Container bias flow",
|
||||
FlowData.builder().container(container).build(),
|
||||
OWNER);
|
||||
executionsService.startExecution(baseline.getId());
|
||||
waitUntilFinal(baseline);
|
||||
assertEquals(ExecutionStatus.SUCCESS, baseline.getContext().getStatus());
|
||||
|
||||
ExecutionObject variant = executionsService.createBiasRerun(
|
||||
baseline.getId(),
|
||||
OWNER,
|
||||
new BiasRerunRequest(
|
||||
List.of(new BiasActivation(container.getId(), List.of(annotation.id()))),
|
||||
ExternalSideEffectPolicy.BLOCK,
|
||||
false));
|
||||
executionsService.startExecution(variant.getId());
|
||||
waitUntilFinal(variant);
|
||||
|
||||
assertEquals(ExecutionStatus.SUCCESS, variant.getContext().getStatus());
|
||||
BiasImpactReport report = biasImpactService.compareFullFlow(baseline.getId(), variant.getId(), true, OWNER);
|
||||
assertTrue(report.immediateImpact().outputChanged());
|
||||
assertEquals(container.getId(), report.nodeId());
|
||||
// Containers are not bias-annotatable at their boundary: no activation
|
||||
// modes of their own; bias participation is via subflow propagation.
|
||||
assertTrue(containerCapabilities.subflowPropagationSupported());
|
||||
assertTrue(containerCapabilities.activationModes().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -567,20 +469,6 @@ class BiasExperimentsIntegrationTest {
|
|||
return annotation(mode, instruction, targetInputs, Map.of());
|
||||
}
|
||||
|
||||
private BlockBiasAnnotation annotation(String id, BiasBehavioralProbe probe) {
|
||||
return new BlockBiasAnnotation(
|
||||
id,
|
||||
BiasCategory.CONFIRMATION_BIAS,
|
||||
BiasSeverity.HIGH,
|
||||
"The node may reinforce an initial conclusion.",
|
||||
"The output can underweight contrary evidence.",
|
||||
"Require independent evidence.",
|
||||
BiasAnnotationStatus.CONFIRMED,
|
||||
BiasAnnotationSource.MANUAL,
|
||||
null,
|
||||
probe);
|
||||
}
|
||||
|
||||
private BlockBiasAnnotation annotation(BiasActivationMode mode, String instruction, List<String> targetInputs,
|
||||
Map<String, Object> mockOutputs) {
|
||||
return new BlockBiasAnnotation(
|
||||
|
|
|
|||
Loading…
Reference in New Issue