sendAndWait method
Future<AssistantMessageEvent?>
sendAndWait(
- String prompt, {
- List<
Attachment> attachments = const [], - MessageDeliveryMode? mode,
- Duration timeout = const Duration(seconds: 60),
Sends a message and waits for the assistant's complete reply.
Returns the last AssistantMessageEvent received before session idle,
matching the upstream Node.js/Go SDK behavior. The full event includes
content, messageId, toolRequests, reasoningOpaque,
reasoningText, encryptedContent, phase, and parentToolCallId.
Returns null if no assistant message was received before idle.
Throws TimeoutException if no reply within timeout (default 60s).
Throws StateError on session errors.
Implementation
Future<AssistantMessageEvent?> sendAndWait(
String prompt, {
List<Attachment> attachments = const [],
MessageDeliveryMode? mode,
Duration timeout = const Duration(seconds: 60),
}) async {
_ensureAlive();
final completer = Completer<AssistantMessageEvent?>();
AssistantMessageEvent? lastMessage;
var sendCompleted = false;
var idleReceived = false;
void completeIfReady() {
if (!sendCompleted || !idleReceived || completer.isCompleted) return;
completer.complete(lastMessage);
}
// Listen for the last assistant.message event and session idle.
// Matches upstream: only captures complete AssistantMessageEvents,
// ignores deltas (which are ephemeral streaming chunks).
final unsub = on((event) {
switch (event) {
case AssistantMessageEvent():
lastMessage = event;
case SessionIdleEvent():
idleReceived = true;
completeIfReady();
case SessionErrorEvent(:final message):
if (!completer.isCompleted) {
completer.completeError(
StateError('Session error: $message'),
);
}
default:
break;
}
});
try {
await send(
prompt,
attachments: attachments,
mode: mode,
);
sendCompleted = true;
completeIfReady();
// Wait with timeout — throw on timeout to match upstream behavior
return await completer.future.timeout(
timeout,
onTimeout: () => throw TimeoutException(
'Timeout after ${timeout.inMilliseconds}ms waiting for '
'session.idle',
timeout,
),
);
} finally {
unsub();
}
}