Atomically check-and-set the ``notified`` flag, then enqueue. WI-3.2 contract: this is the single duplicate-delivery guard. The ``runtime_tasks.update`` mutator atomically reads ``prev.notified`` and (if False) returns a new state with ``notified=True``. The XML is enqueued only whe
(
*,
task_id: str,
description: str,
status: NotificationStatus,
output_file: str,
registry: "RuntimeTaskRegistry",
error: str | None = None,
final_message: str | None = None,
usage: dict[str, int] | None = None,
tool_use_id: str | None = None,
)
| 106 | |
| 107 | |
| 108 | def enqueue_agent_notification( |
| 109 | *, |
| 110 | task_id: str, |
| 111 | description: str, |
| 112 | status: NotificationStatus, |
| 113 | output_file: str, |
| 114 | registry: "RuntimeTaskRegistry", |
| 115 | error: str | None = None, |
| 116 | final_message: str | None = None, |
| 117 | usage: dict[str, int] | None = None, |
| 118 | tool_use_id: str | None = None, |
| 119 | ) -> bool: |
| 120 | """Atomically check-and-set the ``notified`` flag, then enqueue. |
| 121 | |
| 122 | WI-3.2 contract: this is the single duplicate-delivery guard. The |
| 123 | ``runtime_tasks.update`` mutator atomically reads ``prev.notified`` |
| 124 | and (if False) returns a new state with ``notified=True``. The XML |
| 125 | is enqueued only when the mutator's pre-state had ``notified=False``. |
| 126 | |
| 127 | Returns True iff a notification was actually enqueued. |
| 128 | |
| 129 | Two concurrent callers on the same ``task_id`` race against the |
| 130 | registry RLock; the second call sees ``notified=True`` and returns |
| 131 | False without touching the queue. |
| 132 | """ |
| 133 | # Local import to defer the cycle: ``local_agent`` imports |
| 134 | # transcript stuff that imports back through the agent module. |
| 135 | from src.tasks.local_agent import LocalAgentTaskState |
| 136 | |
| 137 | should_enqueue = False |
| 138 | |
| 139 | def _mark_notified(prev: Any) -> Any: |
| 140 | nonlocal should_enqueue |
| 141 | if not isinstance(prev, LocalAgentTaskState): |
| 142 | return prev |
| 143 | if prev.notified: |
| 144 | return prev |
| 145 | should_enqueue = True |
| 146 | return replace(prev, notified=True) |
| 147 | |
| 148 | registry.update(task_id, _mark_notified) |
| 149 | |
| 150 | if not should_enqueue: |
| 151 | return False |
| 152 | |
| 153 | xml = build_task_notification_xml( |
| 154 | task_id=task_id, |
| 155 | description=description, |
| 156 | status=status, |
| 157 | output_file=output_file, |
| 158 | error=error, |
| 159 | final_message=final_message, |
| 160 | usage=usage, |
| 161 | tool_use_id=tool_use_id, |
| 162 | ) |
| 163 | enqueue_pending_notification(value=xml, mode="task-notification") |
| 164 | return True |
| 165 |