maybeSnapshot method
Future<String?>
maybeSnapshot({
- String? status,
- AgentErrorDetails? error,
- String? snapshotId,
- AgentFinishReason? finishReason,
Evaluates whether to save a snapshot to the persistent store.
Implementation
Future<String?> maybeSnapshot({
String? status,
AgentErrorDetails? error,
String? snapshotId,
AgentFinishReason? finishReason,
}) async {
if (_store == null ||
(isDetached && snapshotId != _lastSnapshot?.snapshotId)) {
return _lastSnapshot?.snapshotId;
}
final currentVersion = session.getVersion();
if (currentVersion == _lastSnapshotVersion && status == null) {
return _lastSnapshot?.snapshotId;
}
final currentState = session.getState();
final effectiveId = snapshotId ?? newSnapshotId;
// When an id is reused (e.g. the detached `pending` snapshot is upgraded to
// `completed` under the same id), `_lastSnapshot` already points at that id.
// Inherit its parent instead of pointing the snapshot at itself, which would
// create a self-referential `parentId` and later trip the cycle guard in
// `loadChat`/`getSnapshot`.
final reusingId =
effectiveId != null && effectiveId == _lastSnapshot?.snapshotId;
final parentId = reusingId
? _lastSnapshot?.parentId
: _lastSnapshot?.snapshotId;
// The `invocationEnd` write (the only caller that omits a status) persists
// as `completed` so it stays a valid resume target.
final now = DateTime.now().toUtc().toIso8601String();
final snapshotInput = SessionSnapshot(
snapshotId: effectiveId ?? '',
sessionId: session.sessionId,
createdAt: _lastSnapshot?.createdAt ?? now,
updatedAt: now,
// Stamp an initial heartbeat on a `pending` (detached, in-flight)
// snapshot. A background heartbeat loop refreshes it; if it goes stale
// the snapshot is reported as `expired` on read (worker presumed dead).
heartbeatAt: status == 'pending' ? now : null,
state: currentState,
parentId: parentId,
status: SnapshotStatus(status ?? 'completed'),
finishReason: finishReason,
error: error != null ? _toErrorInfo(error) : null,
);
final assignedId = await _store.saveSnapshot(
effectiveId,
_abortAwareMutator(snapshotInput),
context: context,
);
if (assignedId == null) {
// Snapshot was aborted concurrently; preserve the existing ID.
return effectiveId;
}
snapshotInput.snapshotId = assignedId;
_lastSnapshot = snapshotInput;
_lastSnapshotVersion = currentVersion;
return assignedId;
}