sendUser method
Dispatch a user message: append the user turn, call
system.agents.ask, append the assistant reply (or assistantError
on failure plus optional toolUse turns), and return a structured
result.
Implementation
Future<AgentChatDispatchResult> sendUser(String text) async {
_checkAlive();
final appended = <ChatTurn>[];
final userTurn = ChatTurn(
id: _newId('user'),
role: ChatRole.user,
text: text,
ts: DateTime.now().toUtc(),
agentId: agentId,
);
appended.add(await appendTurn(userTurn));
AgentReply? reply;
try {
reply = await _ask(text);
} catch (err) {
final errTurn = ChatTurn(
id: _newId('err'),
role: ChatRole.assistantError,
text: err.toString(),
ts: DateTime.now().toUtc(),
agentId: agentId,
meta: <String, dynamic>{'error': err.runtimeType.toString()},
);
appended.add(await appendTurn(errTurn));
return AgentChatDispatchResult(
appended: List.unmodifiable(appended),
error: err,
);
}
final assistantTurn = ChatTurn(
id: _newId('asst'),
role: ChatRole.assistant,
text: reply.content,
ts: reply.timestamp.toUtc(),
agentId: agentId,
meta: _replyMeta(reply),
);
appended.add(await appendTurn(assistantTurn));
final calls = reply.toolCalls ?? const <AgentToolCall>[];
if (calls.isNotEmpty) {
final clamped =
calls.length > _turnLimit ? calls.sublist(0, _turnLimit) : calls;
for (final c in clamped) {
final toolTurn = ChatTurn(
id: _newId('tool'),
role: ChatRole.toolUse,
text: c.name,
ts: DateTime.now().toUtc(),
agentId: agentId,
meta: <String, dynamic>{
'toolCallId': c.id,
'arguments': c.arguments,
},
);
appended.add(await appendTurn(toolTurn));
}
if (calls.length > _turnLimit) {
final warn = ChatTurn(
id: _newId('warn'),
role: ChatRole.system,
text: 'turn-limit reached ($_turnLimit) — '
'${calls.length - _turnLimit} additional tool call(s) suppressed',
ts: DateTime.now().toUtc(),
agentId: agentId,
);
appended.add(await appendTurn(warn));
}
}
return AgentChatDispatchResult(
appended: List.unmodifiable(appended),
reply: reply,
);
}