continueRun method
Continues an existing transcript (e.g. from a previous AgentRun).
Implementation
Future<AgentRun> continueRun(List<ChatMessage> transcript) async {
final messages = [...transcript];
final steps = <AgentStep>[];
var input = 0;
var output = 0;
var cached = 0;
final byName = {for (final t in tools) t.name: t};
for (var round = 0; round < maxSteps; round++) {
final response = await model.completeWithTools(
messages,
system: system,
maxTokens: maxTokens,
tools: tools,
);
input += response.usage?.inputTokens ?? 0;
output += response.usage?.outputTokens ?? 0;
cached += response.usage?.cachedInputTokens ?? 0;
if (response.toolCalls.isEmpty) {
messages.add(ChatMessage.assistant(response.text));
return AgentRun(
answer: response.text,
steps: steps,
transcript: messages,
usage: ChatUsage(
inputTokens: input,
outputTokens: output,
cachedInputTokens: cached,
),
);
}
messages.add(
ChatMessage(
ChatRole.assistant,
response.text,
toolCalls: response.toolCalls,
),
);
final results = <ToolResult>[];
for (final call in response.toolCalls) {
final tool = byName[call.name];
AgentStep step;
if (tool == null) {
// Tell the model rather than failing the run: it can pick a real
// tool on the next round.
step = AgentStep(
call: call,
result:
'No tool named "${call.name}". Available: '
'${tools.map((t) => t.name).join(', ')}.',
isError: true,
);
} else {
try {
step = AgentStep(call: call, result: await tool.run(call.input));
} catch (e) {
step = AgentStep(call: call, result: '$e', isError: true);
}
}
steps.add(step);
onStep?.call(step);
results.add(
ToolResult(id: call.id, content: step.result, isError: step.isError),
);
}
messages.add(ChatMessage.toolResults(results));
}
return AgentRun(
answer: '',
steps: steps,
transcript: messages,
usage: ChatUsage(
inputTokens: input,
outputTokens: output,
cachedInputTokens: cached,
),
exhausted: true,
);
}