call method

Future<ChainValues> call(
  1. dynamic input, {
  2. bool returnOnlyOutputs = false,
})

Runs the core logic of this chain with the given values. If memory is not null, it will be used to load and save values.

  • inputs are the inputs to this chain. Assumed to contain all inputs specified in inputKeys, including any inputs added by memory.
  • returnOnlyOutputs if true the chain will only return the outputs of this chain. If false, the chain will return all inputs and outputs.

Returns a dictionary of outputs. It should contain all outputs specified in outputKeys.

Implementation

Future<ChainValues> call(
  final dynamic input, {
  final bool returnOnlyOutputs = false,
}) async {
  ChainValues chainValues;

  if (input is Map) {
    chainValues = input.cast();
  } else {
    chainValues = {inputKeys.firstOrNull ?? defaultInputKey: input};
  }

  if (inputKeys.isNotEmpty) {
    if (chainValues.length < inputKeys.length) {
      throw ArgumentError(
        'This chain ($chainType) requires ${inputKeys.length} input values '
        'but only ${chainValues.length} were provided.',
      );
    }
    final chainValuesKeys = chainValues.keys.toSet();
    final inputKeysDiff = inputKeys.difference(chainValuesKeys);
    if (inputKeysDiff.isNotEmpty) {
      throw ArgumentError(
        'This chain ($chainType) also requires $inputKeysDiff input values.',
      );
    }
  }

  final memory = this.memory;
  if (memory != null) {
    final newValues = await memory.loadMemoryVariables(chainValues);
    chainValues.addAll(newValues);
  }

  final outputValues = await callInternal(chainValues);

  if (memory != null) {
    await memory.saveContext(
      inputValues: chainValues,
      outputValues: outputValues,
    );
  }

  if (outputKeys.isNotEmpty) {
    if (outputValues.length < outputKeys.length) {
      throw ArgumentError(
        'This chain ($chainType) expects ${outputKeys.length} output values '
        'but only ${outputValues.length} were returned.',
      );
    }
    final outputValuesKeys = outputValues.keys.toSet();
    final outputKeysDiff = outputKeys.difference(outputValuesKeys);
    if (outputKeysDiff.isNotEmpty) {
      throw ArgumentError(
        'This chain ($chainType) also expects $outputKeysDiff output values.',
      );
    }
  }

  if (returnOnlyOutputs) {
    return outputValues;
  }

  return {...chainValues, ...outputValues};
}