callInternal method
Call method to be implemented by subclasses (called by call). This is where the core logic of the chain should be implemented.
Implementation
@override
Future<ChainValues> callInternal(final ChainValues inputs) async {
final List<AgentStep> intermediateSteps = [];
// Construct a mapping of tool name to tool for easy lookup
final nameToToolMap = {for (final tool in _internalTools) tool.name: tool};
// Let's start tracking the number of iterations and time elapsed
var iterations = 0;
final stopwatch = Stopwatch()..start();
ChainValues onAgentFinished(final AgentFinish result) {
return {
...result.returnValues,
if (returnIntermediateSteps)
intermediateStepsOutputKey: intermediateSteps,
};
}
// We now enter the agent loop (until it returns something).
while (_shouldContinue(iterations, stopwatch.elapsed)) {
final (result, nextSteps) = await takeNextStep(
nameToToolMap,
inputs,
intermediateSteps,
);
if (result != null) {
return onAgentFinished(result);
}
if (nextSteps != null) {
intermediateSteps.addAll(nextSteps);
if (nextSteps.length == 1) {
final nextStep = nextSteps.first;
final tool = nameToToolMap[nextStep.action.tool];
if (tool != null && tool.returnDirect) {
return onAgentFinished(
AgentFinish(
returnValues: {
agent.returnValues.first: nextStep.observation,
},
),
);
}
}
}
iterations += 1;
}
final stopped = agent.returnStoppedResponse(
earlyStoppingMethod,
intermediateSteps,
);
return onAgentFinished(stopped);
}