@teaflask/assistant 0.6.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (330) hide show
  1. package/README.md +1 -1
  2. package/custom-elements.json +264 -0
  3. package/dist/affordances/aria-dropdowns.js +315 -0
  4. package/dist/affordances/aria-toggles.js +39 -0
  5. package/dist/affordances/dropdown-display.js +129 -0
  6. package/dist/affordances/page-gestures.js +91 -0
  7. package/dist/affordances/prefill-reasons.js +75 -0
  8. package/dist/affordances/prefill.js +113 -62
  9. package/dist/appearance/theme.d.ts +138 -0
  10. package/dist/components/approval-card.js +3 -3
  11. package/dist/components/approval-context.d.ts +20 -0
  12. package/dist/components/assistant-companion.d.ts +15 -0
  13. package/dist/components/assistant-page.d.ts +61 -0
  14. package/dist/components/assistant-palette.d.ts +12 -0
  15. package/dist/components/assistant-palette.js +2 -2
  16. package/dist/components/child-transcript.js +1 -1
  17. package/dist/components/companion-header-disclosure.js +1 -1
  18. package/dist/components/companion-history-menu.js +1 -1
  19. package/dist/components/composer.js +11 -65
  20. package/dist/components/conversation-context.d.ts +6 -0
  21. package/dist/components/conversation-gate-card.js +1 -1
  22. package/dist/components/conversation-view.d.ts +11 -0
  23. package/dist/components/elicitation-context.d.ts +39 -0
  24. package/dist/components/model-picker-chip.js +4 -2
  25. package/dist/components/primitives/button.js +25 -17
  26. package/dist/components/primitives/floating-panel.js +1 -1
  27. package/dist/components/provider-chip.js +8 -1
  28. package/dist/components/question-panel-footer.js +1 -1
  29. package/dist/components/react-tool-view.d.ts +7 -0
  30. package/dist/components/subagent-count-pill.js +2 -2
  31. package/dist/components/subagent-group-row.js +1 -26
  32. package/dist/components/subagent-preview-popover.js +1 -1
  33. package/dist/components/subscription-connect-arms.js +6 -4
  34. package/dist/components/subscription-connect-flow.js +30 -45
  35. package/dist/components/subscription-connected-standing.js +9 -6
  36. package/dist/components/subscription-plan-notice.js +4 -2
  37. package/dist/components/teaflask-assistant-provider.d.ts +99 -0
  38. package/dist/components/teaflask-assistant.d.ts +33 -0
  39. package/dist/components/tool-views/action-view.js +1 -1
  40. package/dist/components/tool-views/parts-classes.d.ts +5 -5
  41. package/dist/components/tool-views/parts-classes.js +5 -5
  42. package/dist/components/tool-views/parts.d.ts +44 -0
  43. package/dist/components/tool-views/questions-view.js +2 -2
  44. package/dist/components/tool-views/view-dom.d.ts +76 -0
  45. package/dist/components/transcript.js +2 -2
  46. package/dist/components/use-assistant-activity.d.ts +5 -0
  47. package/dist/components/use-assistant-conversation.d.ts +99 -2
  48. package/dist/components/use-store-cell.d.ts +5 -0
  49. package/dist/components/use-thread-dispatches.js +8 -366
  50. package/dist/components/use-transcript-folds.js +2 -1
  51. package/dist/components/use-transcript.d.ts +55 -2
  52. package/dist/components/use-transcript.js +7 -2
  53. package/dist/contract/actions-adapter.d.ts +78 -0
  54. package/dist/contract/errors.d.ts +6 -1
  55. package/dist/contract/events.d.ts +1 -3
  56. package/dist/contract/identity.d.ts +1 -1
  57. package/dist/contract/subscriptions.d.ts +2 -2
  58. package/dist/contract/subscriptions.js +1 -1
  59. package/dist/contract/telemetry.d.ts +45 -0
  60. package/dist/contract/threads.d.ts +5 -1
  61. package/dist/core/activity.d.ts +44 -0
  62. package/dist/core/approval-inbox.d.ts +69 -0
  63. package/dist/core/assistant-session-registry.js +15 -0
  64. package/dist/core/composer-attachments.js +82 -0
  65. package/dist/core/composer-input-state.js +1 -0
  66. package/dist/core/composer-policy.d.ts +20 -0
  67. package/dist/core/connection-epoch.d.ts +65 -2
  68. package/dist/core/conversation-adoption.js +3 -0
  69. package/dist/core/conversation-contract.d.ts +112 -1
  70. package/dist/core/conversation-publish.js +1 -0
  71. package/dist/core/conversation-store.d.ts +3 -0
  72. package/dist/core/conversation-store.js +7 -0
  73. package/dist/core/dispatch-poll.js +81 -0
  74. package/dist/core/elicitation-answers.js +12 -0
  75. package/dist/core/elicitation-cards.d.ts +14 -0
  76. package/dist/core/elicitation-pickers.d.ts +16 -0
  77. package/dist/core/execution-handlers.js +3 -3
  78. package/dist/core/memory-provenance-anchors.d.ts +16 -0
  79. package/dist/core/observable-cell.d.ts +12 -0
  80. package/dist/core/pending-decision-gap.d.ts +9 -0
  81. package/dist/core/question-drafts.d.ts +59 -0
  82. package/dist/core/receipt-anchors.d.ts +9 -0
  83. package/dist/core/segment-timing.d.ts +23 -0
  84. package/dist/core/subagent-delivery-anchors.d.ts +7 -0
  85. package/dist/core/subagent-ledger-join.js +176 -0
  86. package/dist/core/subagent-rows.d.ts +68 -0
  87. package/dist/core/thread-dispatch-ledger.js +303 -0
  88. package/dist/core/tool-call-display.d.ts +71 -0
  89. package/dist/core/tool-call-presentation.d.ts +34 -1
  90. package/dist/core/tool-call-presentation.js +0 -1
  91. package/dist/core/tool-schema-anchors.d.ts +6 -0
  92. package/dist/core/tool-view.d.ts +174 -1
  93. package/dist/core/transcript-rows.d.ts +138 -3
  94. package/dist/core/turn-failed-anchors.d.ts +4 -0
  95. package/dist/core/user-turn-ledger.d.ts +3 -0
  96. package/dist/generated/models/apiErrorCode.d.ts +1 -0
  97. package/dist/generated/models/apiErrorCode.js +1 -0
  98. package/dist/generated/models/assistantTurnStatus.d.ts +16 -0
  99. package/dist/generated/models/servingAssistantThreadResponse.d.ts +23 -0
  100. package/dist/generated/models/servingAttachmentResponse.d.ts +29 -0
  101. package/dist/generated/models/servingErrorCode.d.ts +18 -0
  102. package/dist/generated/models/servingTurnAttachmentResponse.d.ts +12 -0
  103. package/dist/generated/models/siteTheme.d.ts +1 -0
  104. package/dist/generated/models/thinkingEffort.d.ts +10 -0
  105. package/dist/generated/models/threadModelPickResponse.d.ts +12 -0
  106. package/dist/headless.d.ts +9 -4
  107. package/dist/index.d.ts +2 -6
  108. package/dist/index.js +0 -3
  109. package/dist/persistence/stored-thread.d.ts +5 -0
  110. package/dist/reader/render.js +7 -4
  111. package/dist/reader/roles.js +28 -1
  112. package/dist/reader/snapshot-node.js +2 -29
  113. package/dist/reader/snapshot-root.js +14 -8
  114. package/dist/reader/snapshot.js +6 -1
  115. package/dist/styles.css +1 -1
  116. package/dist/transport/serving-error.d.ts +21 -0
  117. package/package.json +6 -25
  118. package/dist/affordances/highlight.d.ts +0 -3
  119. package/dist/affordances/prefill.d.ts +0 -14
  120. package/dist/components/activity-rail.d.ts +0 -12
  121. package/dist/components/activity-shelf.d.ts +0 -7
  122. package/dist/components/agent-identity-mark.d.ts +0 -7
  123. package/dist/components/appearance-context.d.ts +0 -14
  124. package/dist/components/approval-card.d.ts +0 -7
  125. package/dist/components/assistant-palette-body.d.ts +0 -3
  126. package/dist/components/assistant-transcript.d.ts +0 -47
  127. package/dist/components/attachment-chips.d.ts +0 -4
  128. package/dist/components/child-transcript.d.ts +0 -22
  129. package/dist/components/companion-drawer-body.d.ts +0 -1
  130. package/dist/components/companion-drawer.d.ts +0 -10
  131. package/dist/components/companion-header-disclosure.d.ts +0 -20
  132. package/dist/components/companion-history-menu.d.ts +0 -15
  133. package/dist/components/companion-mark-image.d.ts +0 -3
  134. package/dist/components/companion-mark-image.js +0 -18
  135. package/dist/components/companion-mark.d.ts +0 -1
  136. package/dist/components/companion-mode-menu.d.ts +0 -15
  137. package/dist/components/composer-attachment-chip.d.ts +0 -7
  138. package/dist/components/composer-banner.d.ts +0 -4
  139. package/dist/components/composer.d.ts +0 -4
  140. package/dist/components/conversation-gate-card.d.ts +0 -8
  141. package/dist/components/conversation-surfaces-provider.d.ts +0 -6
  142. package/dist/components/copy-text-button.d.ts +0 -5
  143. package/dist/components/elicitation-receipt-row.d.ts +0 -4
  144. package/dist/components/human-file-size.d.ts +0 -1
  145. package/dist/components/icons.d.ts +0 -15
  146. package/dist/components/lazy-body.d.ts +0 -4
  147. package/dist/components/markdown/assistant-markdown.d.ts +0 -3
  148. package/dist/components/markdown/code-block.d.ts +0 -4
  149. package/dist/components/markdown/highlight.d.ts +0 -1
  150. package/dist/components/markdown/markdown-structure.d.ts +0 -16
  151. package/dist/components/markdown/memoized-blocks.d.ts +0 -6
  152. package/dist/components/markdown/paced-assistant-markdown.d.ts +0 -4
  153. package/dist/components/markdown/reveal-pacer.d.ts +0 -20
  154. package/dist/components/markdown/shiki-highlighter.d.ts +0 -1
  155. package/dist/components/markdown/streaming-repair.d.ts +0 -1
  156. package/dist/components/markdown/use-highlighted-html.d.ts +0 -1
  157. package/dist/components/markdown/use-paced-reveal.d.ts +0 -5
  158. package/dist/components/memory-updated-footer.d.ts +0 -4
  159. package/dist/components/message-list-row.d.ts +0 -13
  160. package/dist/components/message-list-slots.d.ts +0 -25
  161. package/dist/components/message-list-slots.js +0 -1
  162. package/dist/components/message-list.d.ts +0 -23
  163. package/dist/components/model-picker-chip.d.ts +0 -1
  164. package/dist/components/model-picker-effort.d.ts +0 -4
  165. package/dist/components/model-picker-panels.d.ts +0 -22
  166. package/dist/components/notice-banner.d.ts +0 -8
  167. package/dist/components/operation-icons.d.ts +0 -19
  168. package/dist/components/pretty-print.d.ts +0 -1
  169. package/dist/components/primitives/autofocus.d.ts +0 -1
  170. package/dist/components/primitives/button.d.ts +0 -10
  171. package/dist/components/primitives/cx.d.ts +0 -1
  172. package/dist/components/primitives/dialog.d.ts +0 -7
  173. package/dist/components/primitives/disclosure.d.ts +0 -22
  174. package/dist/components/primitives/file-input.d.ts +0 -5
  175. package/dist/components/primitives/floating-panel.d.ts +0 -15
  176. package/dist/components/primitives/kbd.d.ts +0 -2
  177. package/dist/components/primitives/sheet.d.ts +0 -11
  178. package/dist/components/primitives/sheet.js +0 -18
  179. package/dist/components/primitives/textarea.d.ts +0 -7
  180. package/dist/components/primitives/use-dock-reflow.d.ts +0 -2
  181. package/dist/components/primitives/use-swipe-dismiss.d.ts +0 -17
  182. package/dist/components/provider-chip.d.ts +0 -8
  183. package/dist/components/question-panel-answers.d.ts +0 -29
  184. package/dist/components/question-panel-footer.d.ts +0 -9
  185. package/dist/components/question-panel.d.ts +0 -4
  186. package/dist/components/reasoning-row.d.ts +0 -4
  187. package/dist/components/receipt-rows.d.ts +0 -3
  188. package/dist/components/run-status-announcer.d.ts +0 -5
  189. package/dist/components/scroll-follow-guards.d.ts +0 -1
  190. package/dist/components/served-suggestions.d.ts +0 -3
  191. package/dist/components/slot-boundary.d.ts +0 -11
  192. package/dist/components/standing-poll.d.ts +0 -1
  193. package/dist/components/streaming-states.d.ts +0 -12
  194. package/dist/components/subagent-count-pill.d.ts +0 -8
  195. package/dist/components/subagent-current-work.d.ts +0 -6
  196. package/dist/components/subagent-delegation-surface.d.ts +0 -9
  197. package/dist/components/subagent-delivery-divider.d.ts +0 -5
  198. package/dist/components/subagent-drill-in.d.ts +0 -8
  199. package/dist/components/subagent-execution-work.d.ts +0 -3
  200. package/dist/components/subagent-group-row.d.ts +0 -26
  201. package/dist/components/subagent-preview-popover.d.ts +0 -8
  202. package/dist/components/subscription-connect-arms.d.ts +0 -25
  203. package/dist/components/subscription-connect-flow.d.ts +0 -60
  204. package/dist/components/subscription-connected-standing.d.ts +0 -16
  205. package/dist/components/subscription-plan-notice.d.ts +0 -1
  206. package/dist/components/subscription-recheck.d.ts +0 -10
  207. package/dist/components/surface-boundary.d.ts +0 -8
  208. package/dist/components/suspension-surfaces.d.ts +0 -3
  209. package/dist/components/thread-list.d.ts +0 -16
  210. package/dist/components/tool-arguments-summary.d.ts +0 -2
  211. package/dist/components/tool-call-rows.d.ts +0 -10
  212. package/dist/components/tool-row.d.ts +0 -7
  213. package/dist/components/tool-view-registry-context.d.ts +0 -3
  214. package/dist/components/tool-view-slot.d.ts +0 -11
  215. package/dist/components/tool-views/action-view.d.ts +0 -1
  216. package/dist/components/tool-views/command-view.d.ts +0 -1
  217. package/dist/components/tool-views/docs-search-view.d.ts +0 -10
  218. package/dist/components/tool-views/file-edit-view.d.ts +0 -1
  219. package/dist/components/tool-views/questions-view.d.ts +0 -1
  220. package/dist/components/transcript.d.ts +0 -3
  221. package/dist/components/use-agent-subscriber.d.ts +0 -3
  222. package/dist/components/use-agent-subscriber.js +0 -13
  223. package/dist/components/use-answer-list-fold.d.ts +0 -6
  224. package/dist/components/use-assistant-surface-presence.d.ts +0 -2
  225. package/dist/components/use-child-replay-stream.d.ts +0 -20
  226. package/dist/components/use-latest-ref.d.ts +0 -2
  227. package/dist/components/use-member-toggle-outrank.d.ts +0 -6
  228. package/dist/components/use-perch-clearance.d.ts +0 -2
  229. package/dist/components/use-question-panel-keys.d.ts +0 -32
  230. package/dist/components/use-register-assistant-surface.d.ts +0 -2
  231. package/dist/components/use-resolved-theme-mode.d.ts +0 -3
  232. package/dist/components/use-roster-disclosure.d.ts +0 -20
  233. package/dist/components/use-roster-preview.d.ts +0 -24
  234. package/dist/components/use-thread-dispatches.d.ts +0 -8
  235. package/dist/components/use-transcript-folds.d.ts +0 -26
  236. package/dist/components/user-message.d.ts +0 -6
  237. package/dist/contract/actions-adapter.js +0 -1
  238. package/dist/contract/assistant-config.js +0 -1
  239. package/dist/contract/dispatches.d.ts +0 -15
  240. package/dist/contract/errors.js +0 -1
  241. package/dist/contract/identity.js +0 -1
  242. package/dist/core/activity-title.d.ts +0 -1
  243. package/dist/core/agent-identity.d.ts +0 -2
  244. package/dist/core/approval-decision.d.ts +0 -6
  245. package/dist/core/approval-resolved.d.ts +0 -7
  246. package/dist/core/assistant-prose.d.ts +0 -2
  247. package/dist/core/assistant-session-registry.d.ts +0 -51
  248. package/dist/core/attachment-uploads.d.ts +0 -5
  249. package/dist/core/block-timing-anchors.d.ts +0 -5
  250. package/dist/core/companion-drawer-flag.d.ts +0 -4
  251. package/dist/core/companion-presence.d.ts +0 -7
  252. package/dist/core/composer-input-state.d.ts +0 -8
  253. package/dist/core/connection-driver.d.ts +0 -3
  254. package/dist/core/conversation-adoption.d.ts +0 -13
  255. package/dist/core/conversation-contract.js +0 -1
  256. package/dist/core/conversation-publish.d.ts +0 -8
  257. package/dist/core/conversation-refresh.d.ts +0 -4
  258. package/dist/core/conversation-send.d.ts +0 -6
  259. package/dist/core/disposable-subscriber.d.ts +0 -6
  260. package/dist/core/disposable-subscriber.js +0 -18
  261. package/dist/core/dock-reflow.d.ts +0 -5
  262. package/dist/core/elicitation-answers.d.ts +0 -7
  263. package/dist/core/epoch-sync.d.ts +0 -12
  264. package/dist/core/error-copy.d.ts +0 -3
  265. package/dist/core/execution-driver.d.ts +0 -37
  266. package/dist/core/host-fill.d.ts +0 -1
  267. package/dist/core/hotkey.d.ts +0 -18
  268. package/dist/core/identity-pair.d.ts +0 -14
  269. package/dist/core/idle-recheck.d.ts +0 -3
  270. package/dist/core/messages-cell.d.ts +0 -11
  271. package/dist/core/perch-clearance.d.ts +0 -19
  272. package/dist/core/question-receipt.d.ts +0 -11
  273. package/dist/core/reasoning-copy.d.ts +0 -2
  274. package/dist/core/run-folds.d.ts +0 -43
  275. package/dist/core/run-status.d.ts +0 -4
  276. package/dist/core/settle-refresh.d.ts +0 -9
  277. package/dist/core/step-caption.d.ts +0 -2
  278. package/dist/core/stop-copy.d.ts +0 -1
  279. package/dist/core/stop-settle.d.ts +0 -5
  280. package/dist/core/stream-trouble.d.ts +0 -5
  281. package/dist/core/subagent-brief.d.ts +0 -3
  282. package/dist/core/subagent-presence.d.ts +0 -10
  283. package/dist/core/subagent-roster.d.ts +0 -35
  284. package/dist/core/surface-registry.d.ts +0 -16
  285. package/dist/core/suspension-queue.d.ts +0 -14
  286. package/dist/core/tail-slot-pool.d.ts +0 -13
  287. package/dist/core/time-labels.d.ts +0 -7
  288. package/dist/core/tool-call-display-anchors.d.ts +0 -11
  289. package/dist/core/tool-cancel-anchors.d.ts +0 -5
  290. package/dist/core/tool-decision-anchors.d.ts +0 -6
  291. package/dist/core/tool-error-anchors.d.ts +0 -5
  292. package/dist/core/tool-flag-anchors.d.ts +0 -9
  293. package/dist/core/tool-offload-anchors.d.ts +0 -5
  294. package/dist/core/tool-outcome.d.ts +0 -9
  295. package/dist/core/tool-refusal-anchors.d.ts +0 -5
  296. package/dist/core/tool-result-envelope.d.ts +0 -3
  297. package/dist/core/tool-sentence-anchors.d.ts +0 -11
  298. package/dist/core/transcript-lease.d.ts +0 -2
  299. package/dist/core/turn-failure-copy.d.ts +0 -4
  300. package/dist/core/turns-backfill.d.ts +0 -14
  301. package/dist/core/wire-sentence-cap.d.ts +0 -1
  302. package/dist/generated/serving.d.ts +0 -38
  303. package/dist/markdown.d.ts +0 -4
  304. package/dist/markdown.js +0 -4
  305. package/dist/persistence/execution-ledger.d.ts +0 -7
  306. package/dist/persistence/panel-mode.d.ts +0 -6
  307. package/dist/persistence/plan-notice.d.ts +0 -3
  308. package/dist/reader/accessible-name.d.ts +0 -3
  309. package/dist/reader/interactivity.d.ts +0 -11
  310. package/dist/reader/layout-probe.d.ts +0 -29
  311. package/dist/reader/line-diff.d.ts +0 -1
  312. package/dist/reader/read-page.d.ts +0 -12
  313. package/dist/reader/redaction.d.ts +0 -3
  314. package/dist/reader/render.d.ts +0 -3
  315. package/dist/reader/roles.d.ts +0 -8
  316. package/dist/reader/snapshot-compaction.d.ts +0 -5
  317. package/dist/reader/snapshot-node.d.ts +0 -4
  318. package/dist/reader/snapshot-root.d.ts +0 -15
  319. package/dist/reader/snapshot.d.ts +0 -60
  320. package/dist/reader/visibility.d.ts +0 -8
  321. package/dist/scroll.d.ts +0 -1
  322. package/dist/scroll.js +0 -1
  323. package/dist/transcript-ui.d.ts +0 -15
  324. package/dist/transcript-ui.js +0 -8
  325. package/dist/transcript.d.ts +0 -43
  326. package/dist/transcript.js +0 -38
  327. package/dist/transport/actions-adapter.d.ts +0 -4
  328. package/dist/transport/door-budget.d.ts +0 -4
  329. package/dist/transport/serving-api.d.ts +0 -33
  330. package/dist/transport/serving-fetch.d.ts +0 -11
@@ -61,6 +61,7 @@ export declare class AssistantConversationStore {
61
61
  _modelPickDirty: boolean;
62
62
  readonly _composerInput: ObservableCell<ComposerInput>;
63
63
  _nextUnboundScope: number;
64
+ _composerInputResets: number;
64
65
  _composerFocusOwned: string | null;
65
66
  _composerCaretReturnPending: string | null;
66
67
  _tier: VisitorTier | null;
@@ -78,6 +79,7 @@ export declare class AssistantConversationStore {
78
79
  _deliveryProbeRearm: boolean;
79
80
  _idleRecheckTimer: ReturnType<typeof setInterval> | null;
80
81
  _idleRecheckInFlight: boolean;
82
+ _disarmDispatchPoll: (() => void) | null;
81
83
  _disposed: boolean;
82
84
  _epoch: ConnectionEpoch | null;
83
85
  _epochResume: StreamResumeStore | null;
@@ -102,6 +104,7 @@ export declare class AssistantConversationStore {
102
104
  noteComposerFocus: (owner: string | null) => void;
103
105
  takeComposerCaretReturn: (surface: string) => boolean;
104
106
  uploadAttachment: (file: File) => Promise<ServingAttachment>;
107
+ addComposerFiles: (files: Iterable<File>) => Promise<void>;
105
108
  mintAttachmentDownloadUrl: (attachmentId: string) => Promise<MintedDownloadUrl>;
106
109
  acquireTranscriptLease: (surface: string) => (() => void);
107
110
  submitApprovalDecision: (card: ApprovalCardModel, decision: ApprovalDecisionInput) => Promise<void>;
@@ -1,6 +1,7 @@
1
1
  import { IDLE_ACTIVITY, } from "./activity.js";
2
2
  import { noteDispatchSettledFromStore, refreshConversationFromStore, } from "./conversation-refresh.js";
3
3
  import { mintAttachmentDownloadUrlFromStore, uploadAttachmentFromStore, } from "./attachment-uploads.js";
4
+ import { addComposerFilesFromStore } from "./composer-attachments.js";
4
5
  import { handleUserMessageInjectedFromStore, markComposerRefocusHandledFromStore, sendMessageFromStore, stopTurnFromStore, } from "./conversation-send.js";
5
6
  import { noteComposerFocusFromStore, setComposerAttachmentsFromStore, setComposerDraftFromStore, setModelPickFromStore, takeComposerCaretReturnFromStore, } from "./composer-input-state.js";
6
7
  import { submitApprovalDecisionFromStore } from "./approval-decision.js";
@@ -12,6 +13,7 @@ import { SettleRefreshScheduler } from "./settle-refresh.js";
12
13
  import { handleStreamClosedQuietlyFromStore, handleStreamErrorFromStore, handleWorkflowRestartedFromStore, retryStreamFromStore, } from "./stream-trouble.js";
13
14
  import { acquireTranscriptLeaseFromStore } from "./transcript-lease.js";
14
15
  import { clearIdleRecheck, syncIdleRecheck } from "./idle-recheck.js";
16
+ import { armDispatchPoll, disarmDispatchPoll } from "./dispatch-poll.js";
15
17
  import { ConsumedInterruptFold } from "./consumed-interrupts.js";
16
18
  import { composerSnapshotOf, conversationSnapshotOf, publishStore, } from "./conversation-publish.js";
17
19
  import { retireEpoch } from "./epoch-sync.js";
@@ -82,6 +84,7 @@ export class AssistantConversationStore {
82
84
  attachments: [],
83
85
  });
84
86
  _nextUnboundScope = 1;
87
+ _composerInputResets = 0;
85
88
  _composerFocusOwned = null;
86
89
  _composerCaretReturnPending = null;
87
90
  _tier = null;
@@ -103,6 +106,7 @@ export class AssistantConversationStore {
103
106
  _deliveryProbeRearm = false;
104
107
  _idleRecheckTimer = null;
105
108
  _idleRecheckInFlight = false;
109
+ _disarmDispatchPoll = null;
106
110
  _disposed = false;
107
111
  _epoch = null;
108
112
  _epochResume = null;
@@ -157,6 +161,7 @@ export class AssistantConversationStore {
157
161
  this.resumeStoredThread();
158
162
  loadHistoryOnceExpected(this);
159
163
  syncIdleRecheck(this);
164
+ armDispatchPoll(this);
160
165
  }
161
166
  setTier(tier) {
162
167
  if (this._tier === tier) {
@@ -172,6 +177,7 @@ export class AssistantConversationStore {
172
177
  this._settleScheduler.dispose();
173
178
  this._gapGate.dispose();
174
179
  clearIdleRecheck(this);
180
+ disarmDispatchPoll(this);
175
181
  retireEpoch(this);
176
182
  }
177
183
  resumeStoredThread = () => {
@@ -196,6 +202,7 @@ export class AssistantConversationStore {
196
202
  };
197
203
  takeComposerCaretReturn = (surface) => takeComposerCaretReturnFromStore(this, surface);
198
204
  uploadAttachment = async (file) => uploadAttachmentFromStore(this, file);
205
+ addComposerFiles = async (files) => addComposerFilesFromStore(this, files);
199
206
  mintAttachmentDownloadUrl = async (attachmentId) => mintAttachmentDownloadUrlFromStore(this, attachmentId);
200
207
  acquireTranscriptLease = (surface) => acquireTranscriptLeaseFromStore(this, surface);
201
208
  submitApprovalDecision = async (card, decision) => submitApprovalDecisionFromStore(this, card, decision);
@@ -0,0 +1,81 @@
1
+ import { demandInputOfMessages, dispatchDemandOf, dispatchJoinKeyOf, RESUME_SUBAGENT_TOOL_NAME, staleDeliveredOrdinalsKeyOf, } from "./subagent-ledger-join.js";
2
+ import { DISPATCH_SUBAGENT_TOOL_NAME } from "./subagent-rows.js";
3
+ import { EMPTY_THREAD_DISPATCHES, threadDispatchLedgerFor, } from "./thread-dispatch-ledger.js";
4
+ export function armDispatchPoll(store) {
5
+ if (store._disarmDispatchPoll !== null) {
6
+ return;
7
+ }
8
+ const ledger = threadDispatchLedgerFor(store.deps.session);
9
+ ledger.setSettleListener(store, store.noteDispatchSettled);
10
+ ledger.setPauseListener(store, store.noteDispatchPaused);
11
+ let queued = false;
12
+ let lastTapKey = "";
13
+ const judge = () => {
14
+ queued = false;
15
+ if (store._disposed || store._disarmDispatchPoll === null) {
16
+ return;
17
+ }
18
+ lastTapKey = _judgeDemand(store, ledger, lastTapKey);
19
+ };
20
+ const schedule = () => {
21
+ if (queued) {
22
+ return;
23
+ }
24
+ queued = true;
25
+ queueMicrotask(judge);
26
+ };
27
+ const unsubscribes = [
28
+ store.messages.subscribe(schedule),
29
+ store.markerAnchors.subscribe(schedule),
30
+ store.connection.subscribe(schedule),
31
+ ledger.cell.subscribe(schedule),
32
+ ];
33
+ store._disarmDispatchPoll = () => {
34
+ for (const unsubscribe of unsubscribes) {
35
+ unsubscribe();
36
+ }
37
+ ledger.setDemand(store, null);
38
+ ledger.setSettleListener(store, null);
39
+ ledger.setPauseListener(store, null);
40
+ };
41
+ schedule();
42
+ }
43
+ export function disarmDispatchPoll(store) {
44
+ const disarm = store._disarmDispatchPoll;
45
+ if (disarm === null) {
46
+ return;
47
+ }
48
+ store._disarmDispatchPoll = null;
49
+ disarm();
50
+ }
51
+ export function noteThreadRead(store, threadId) {
52
+ threadDispatchLedgerFor(store.deps.session).noteThreadAnswered(threadId);
53
+ }
54
+ function _judgeDemand(store, ledger, lastTapKey) {
55
+ const threadId = store.connection.get()?.threadId ?? null;
56
+ const messages = store.messages.get();
57
+ if (threadId === null || !_delegates(messages)) {
58
+ ledger.setDemand(store, null);
59
+ return "";
60
+ }
61
+ const input = demandInputOfMessages(messages, store.markerAnchors.get());
62
+ const read = ledger.cell.get();
63
+ const map = read !== null && read.threadId === threadId
64
+ ? read.map
65
+ : EMPTY_THREAD_DISPATCHES;
66
+ ledger.setDemand(store, {
67
+ threadId,
68
+ ...dispatchDemandOf(input, map),
69
+ joinKey: dispatchJoinKeyOf(input),
70
+ });
71
+ const tapKey = staleDeliveredOrdinalsKeyOf(input, map);
72
+ if (tapKey !== "" && tapKey !== lastTapKey) {
73
+ void ledger.refresh(threadId);
74
+ }
75
+ return tapKey;
76
+ }
77
+ function _delegates(messages) {
78
+ return messages.some((message) => message.role === "assistant" &&
79
+ (message.toolCalls ?? []).some((call) => call.function.name === DISPATCH_SUBAGENT_TOOL_NAME ||
80
+ call.function.name === RESUME_SUBAGENT_TOOL_NAME));
81
+ }
@@ -14,6 +14,7 @@ async function _deliverQuestionSetReport(store, card, result, answered) {
14
14
  const epoch = store._epoch;
15
15
  const active = store._active;
16
16
  if (epoch === null || active === null) {
17
+ _stampAnswerNotSent(store, card);
17
18
  return;
18
19
  }
19
20
  const inbox = epoch.executionInbox;
@@ -57,6 +58,17 @@ async function _deliverQuestionSetReport(store, card, result, answered) {
57
58
  publishIfCurrent();
58
59
  }
59
60
  }
61
+ function _stampAnswerNotSent(store, card) {
62
+ store._elicitationErrors.set(card.interruptId, ANSWER_NOT_SENT_SENTENCE);
63
+ const cards = store._elicitationsCell.get();
64
+ const next = cards.map((item) => item.interruptId === card.interruptId &&
65
+ item.errorSentence !== ANSWER_NOT_SENT_SENTENCE
66
+ ? { ...item, errorSentence: ANSWER_NOT_SENT_SENTENCE }
67
+ : item);
68
+ if (next.some((item, index) => item !== cards[index])) {
69
+ store._elicitationsCell.set(next);
70
+ }
71
+ }
60
72
  function _turnNoLongerAwaitingToolResults(error) {
61
73
  return (error instanceof ServingApiError &&
62
74
  error.code === "ASSISTANT_TURN_NOT_AWAITING_TOOL_RESULTS");
@@ -10,8 +10,18 @@ interface ElicitationCardBase {
10
10
  status: ElicitationCardStatus;
11
11
  errorSentence: string | null;
12
12
  }
13
+ /**
14
+ * A set of up to five questions the agent asked the visitor, answered together
15
+ * in one submission or dismissed together.
16
+ */
13
17
  export interface QuestionSetCardModel extends ElicitationCardBase {
18
+ /** The questions, in the order the visitor should see them. */
14
19
  questions: readonly QuestionModel[];
20
+ /**
21
+ * What this page submitted, either the answers or a cancellation. Null
22
+ * before it submits, and for sets answered elsewhere or earlier in the
23
+ * conversation, where the transcript's tool row shows the outcome.
24
+ */
15
25
  answered: AnsweredQuestions | null;
16
26
  }
17
27
  export type AnsweredQuestions = {
@@ -23,6 +33,10 @@ export type AnsweredQuestions = {
23
33
  } | {
24
34
  kind: "cancelled";
25
35
  };
36
+ /**
37
+ * A request from the agent for the visitor to answer questions; currently
38
+ * always a question set.
39
+ */
26
40
  export type ElicitationCardModel = QuestionSetCardModel;
27
41
  export declare function elicitationCardsOf(entries: readonly ExecutionEntryModel[], errorSentences: ReadonlyMap<string, string>, questionAnswers?: ReadonlyMap<string, AnsweredQuestions>): ElicitationCardModel[];
28
42
  export declare function sameElicitationCards(a: readonly ElicitationCardModel[], b: readonly ElicitationCardModel[]): boolean;
@@ -1,11 +1,27 @@
1
+ /** One suggested answer to a question. */
1
2
  export interface QuestionOptionModel {
3
+ /**
4
+ * The suggestion as the visitor reads it; if they pick it, submit this
5
+ * exact text as their answer.
6
+ */
2
7
  text: string;
8
+ /** A one-line explanation of the suggestion, or null when there is none. */
3
9
  description: string | null;
4
10
  }
11
+ /** One question in a question set. */
5
12
  export interface QuestionModel {
13
+ /**
14
+ * The question's id, unique within its set; use it as the id of its answer.
15
+ */
6
16
  id: string;
17
+ /** A short label for the question, a few words long. */
7
18
  heading: string;
19
+ /** The question, exactly as the visitor should read it. */
8
20
  prompt: string;
21
+ /**
22
+ * Suggested answers, up to eight; empty for an open question. Always let
23
+ * the visitor write their own answer as well.
24
+ */
9
25
  options: readonly QuestionOptionModel[];
10
26
  }
11
27
  export declare function askQuestionsActionOf(action: Record<string, unknown> | null): {
@@ -55,7 +55,7 @@ export function executionHandlersFor(navigate, executeActionIntent, threadId) {
55
55
  }
56
56
  handlers.set(READ_PAGE_REQUEST_KIND, (entry) => _readPageOutcomeOf(threadId, entry));
57
57
  handlers.set(HIGHLIGHT_REQUEST_KIND, (entry) => Promise.resolve(_highlightOutcomeOf(entry)));
58
- handlers.set(PREFILL_FORM_REQUEST_KIND, (entry) => Promise.resolve(_prefillFormOutcomeOf(entry)));
58
+ handlers.set(PREFILL_FORM_REQUEST_KIND, (entry) => _prefillFormOutcomeOf(entry));
59
59
  return handlers;
60
60
  }
61
61
  async function _navigateOutcomeOf(navigate, entry) {
@@ -316,13 +316,13 @@ function _highlightFailedOutcome(error) {
316
316
  },
317
317
  };
318
318
  }
319
- function _prefillFormOutcomeOf(entry) {
319
+ async function _prefillFormOutcomeOf(entry) {
320
320
  const fields = _prefillFieldsOf(entry.action);
321
321
  if (fields === null) {
322
322
  return UNUSABLE_FIELDS_OUTCOME;
323
323
  }
324
324
  try {
325
- const result = prefilledFieldsReport(fields);
325
+ const result = await prefilledFieldsReport(fields, browserLayoutProbe());
326
326
  return { ok: true, result: { ...result } };
327
327
  }
328
328
  catch (error) {
@@ -1,7 +1,23 @@
1
1
  import type { AgentSubscriber } from "@ag-ui/client";
2
+ /**
3
+ * A notice that the assistant saved a memory. It never contains the memory's
4
+ * content.
5
+ */
2
6
  export interface MemoryUpdated {
7
+ /**
8
+ * The saved memory's id; a repeated report of the same save carries the
9
+ * same id, so use it to de-duplicate.
10
+ */
3
11
  memoryId: string;
12
+ /**
13
+ * Who the memory is for: "org" is shared across all your users, "user" is
14
+ * private to the current user. Show any other value generically.
15
+ */
4
16
  scope: string;
17
+ /**
18
+ * A short sentence for the user saying a memory was saved, not the memory
19
+ * itself.
20
+ */
5
21
  summary: string;
6
22
  }
7
23
  export declare const EMPTY_MEMORY_PROVENANCE_ANCHORS: ReadonlyMap<string, MemoryUpdated>;
@@ -1,5 +1,17 @@
1
+ /**
2
+ * An observable value from the assistant, readable without React (use useCell
3
+ * inside React).
4
+ */
1
5
  export interface ReadonlyCell<T> {
6
+ /**
7
+ * Returns the current value. The returned object only changes identity when
8
+ * the value changes, so you can compare by reference.
9
+ */
2
10
  get: () => T;
11
+ /**
12
+ * Calls the listener after every change and returns a function that
13
+ * unsubscribes it.
14
+ */
3
15
  subscribe: (listener: () => void) => () => void;
4
16
  }
5
17
  export declare class ObservableCell<T> implements ReadonlyCell<T> {
@@ -9,8 +9,17 @@ export interface GapJudgeableTurn {
9
9
  interface InterruptHolder {
10
10
  interruptId: string;
11
11
  }
12
+ /**
13
+ * The agent is waiting on requests that nothing on this page can show or
14
+ * answer, which usually means the conversation needs reloading.
15
+ */
12
16
  export interface PendingDecisionGap {
17
+ /** The id of the waiting turn. */
13
18
  turnId: string;
19
+ /**
20
+ * The ids of the waiting requests (approvals, questions or page actions)
21
+ * that have nothing on this page to answer them.
22
+ */
14
23
  missingInterruptIds: readonly string[];
15
24
  }
16
25
  export declare function pendingDecisionGapOf(turn: GapJudgeableTurn | null, approvalCards: readonly InterruptHolder[], elicitationCards: readonly InterruptHolder[], executionEntries: readonly InterruptHolder[], consumedInterruptIds?: ReadonlySet<string>): PendingDecisionGap | null;
@@ -4,29 +4,88 @@ type ActiveChoice = {
4
4
  } | {
5
5
  kind: "custom";
6
6
  } | null;
7
+ /** The visitor's unsent answer to one question. */
7
8
  export interface QuestionAnswerDraft {
9
+ /**
10
+ * The selected answer, either { kind: "option", text } for a suggestion, {
11
+ * kind: "custom" } for the visitor's own text, or null when nothing is
12
+ * selected yet.
13
+ */
8
14
  active: ActiveChoice;
15
+ /**
16
+ * The visitor's own typed answer. Kept when they select a suggestion
17
+ * instead, so they can switch back.
18
+ */
9
19
  customText: string;
10
20
  }
21
+ /** The visitor's unsent answers to one question set. */
11
22
  export interface QuestionSetDraft {
23
+ /** Index of the question the visitor is on, starting at 0. */
12
24
  cursor: number;
25
+ /**
26
+ * Unsent answers keyed by question id; questions the visitor hasn't touched
27
+ * are absent.
28
+ */
13
29
  answers: ReadonlyMap<string, QuestionAnswerDraft>;
14
30
  }
15
31
  export interface QuestionLike {
16
32
  id: string;
17
33
  }
18
34
  export declare const MAX_ANSWER_TEXT_CHARS = 1900;
35
+ /**
36
+ * Holds the visitor's unsent answers to question sets, keyed by the card's
37
+ * interruptId then the question's id. Subscribe to it (for example with React's
38
+ * useSyncExternalStore and get) to re-render as answers change.
39
+ */
19
40
  export declare class QuestionDraftStore {
20
41
  private readonly drafts;
21
42
  private readonly listeners;
43
+ /**
44
+ * Returns the unsent answers for one question set, or an empty draft
45
+ * (cursor 0, no answers) if nothing has been entered. The same object is
46
+ * returned until that draft changes.
47
+ */
22
48
  get: (interruptId: string) => QuestionSetDraft;
49
+ /**
50
+ * Calls the listener after any draft changes and returns a function that
51
+ * unsubscribes it.
52
+ */
23
53
  subscribe: (listener: () => void) => (() => void);
54
+ /**
55
+ * True when the visitor has selected or typed anything for this question
56
+ * set; use it to confirm before discarding on cancel.
57
+ */
24
58
  hasContent(interruptId: string): boolean;
59
+ /**
60
+ * Selects the suggestion with this text as the answer to one question,
61
+ * keeping any text the visitor typed.
62
+ */
25
63
  selectOption(interruptId: string, questionId: string, text: string): void;
64
+ /**
65
+ * Selects the visitor's own typed answer for one question, without changing
66
+ * its text.
67
+ */
26
68
  selectCustom(interruptId: string, questionId: string): void;
69
+ /**
70
+ * Sets the visitor's own answer to one question and selects it. Control
71
+ * characters are removed, except that vertical tabs and form feeds become
72
+ * line breaks.
73
+ */
27
74
  setCustomText(interruptId: string, questionId: string, text: string): void;
75
+ /**
76
+ * Records which question the visitor is on (an index into the set's
77
+ * questions), so returning to the set shows the same question.
78
+ */
28
79
  setCursor(interruptId: string, cursor: number): void;
80
+ /**
81
+ * Discards the unsent answers for one question set. Answers are already
82
+ * cleared after a successful submit or cancel.
83
+ */
29
84
  clear(interruptId: string): void;
85
+ /**
86
+ * Discards the unsent answers for every question set. Already done when the
87
+ * visitor switches or starts a conversation.
88
+ */
30
89
  clearAll(): void;
31
90
  private updateAnswer;
32
91
  private notify;
@@ -1,6 +1,15 @@
1
1
  import type { AgentSubscriber } from "@ag-ui/client";
2
+ /**
3
+ * Notice sentences attached to one message, split by whether they are shown
4
+ * before or after it.
5
+ */
2
6
  export interface AnchoredReceipts {
7
+ /**
8
+ * Sentences shown before the message. The package places failure notices
9
+ * after the message, so this is normally empty.
10
+ */
3
11
  before: string[];
12
+ /** Sentences shown after the message. */
4
13
  after: string[];
5
14
  }
6
15
  export declare function receiptOf(value: unknown): string | null;
@@ -1,13 +1,36 @@
1
+ /**
2
+ * When a message or tool call started and ended, by the server's clock in
3
+ * milliseconds since the Unix epoch.
4
+ */
1
5
  export interface BlockTiming {
6
+ /** The earliest server timestamp seen for it, or null when unknown. */
2
7
  startedAtMs: number | null;
8
+ /**
9
+ * The latest server timestamp seen for it, or null when unknown. Equals
10
+ * startedAtMs until its end arrives.
11
+ */
3
12
  settledAtMs: number | null;
4
13
  }
14
+ /**
15
+ * A duration that is either unknown (hide it) or measured in milliseconds;
16
+ * render a measured value under 1000 as "<1s" rather than "0s".
17
+ */
5
18
  export type SegmentDuration = {
6
19
  kind: "unknown";
7
20
  } | {
8
21
  kind: "measured";
9
22
  durationMs: number;
10
23
  };
24
+ /**
25
+ * How long the given blocks took together, from the earliest to the latest
26
+ * server timestamp among them, or unknown when none has a timestamp.
27
+ */
11
28
  export declare function settledFoldDurationOf(members: readonly BlockTiming[]): SegmentDuration;
12
29
  export declare function durationLabelOf(durationMs: number): string;
30
+ /**
31
+ * Time elapsed from the earliest server timestamp among the given blocks to
32
+ * `nowMs` (milliseconds since the Unix epoch), or unknown when none has a
33
+ * timestamp. Passing Date.now() includes any difference between the device
34
+ * clock and the server clock.
35
+ */
13
36
  export declare function activeFoldElapsedOf(members: readonly BlockTiming[], nowMs: number): SegmentDuration;
@@ -1,7 +1,14 @@
1
1
  import type { AgentSubscriber } from "@ag-ui/client";
2
+ /** One finished sub-agent whose result a turn reports. */
2
3
  export interface DeliveredResult {
4
+ /**
5
+ * The sub-agent's number within the conversation, matching
6
+ * DispatchReceipt.ordinal of its dispatch.
7
+ */
3
8
  ordinal: number;
9
+ /** A short excerpt of the task the sub-agent was given. */
4
10
  label: string;
11
+ /** True when the sub-agent succeeded, false when it failed. */
5
12
  succeeded: boolean;
6
13
  }
7
14
  export declare const EMPTY_SUBAGENT_DELIVERY_ANCHORS: ReadonlyMap<string, DeliveredResult[]>;
@@ -0,0 +1,176 @@
1
+ import { dispatchFailed, dispatchIsPaused, dispatchIsRunning, } from "../contract/dispatches.js";
2
+ import { subagentIdentityTokenOf } from "./agent-identity.js";
3
+ import { DISPATCH_SUBAGENT_TOOL_NAME, dispatchReceiptOf, withSubagentGroups, } from "./subagent-rows.js";
4
+ export function resolvedSubagentEntryOf(entry, byOrdinal) {
5
+ const ledger = entry.receipt != null ? byOrdinal.get(entry.receipt.ordinal) : undefined;
6
+ const ledgerLabel = ledger !== undefined && ledger.label !== "" ? ledger.label : null;
7
+ const childSessionId = ledger !== undefined && entry.receipt?.childSessionId != null
8
+ ? entry.receipt.childSessionId
9
+ : null;
10
+ const running = ledger !== undefined ? dispatchIsRunning(ledger) : entry.running;
11
+ const failed = ledger !== undefined ? dispatchFailed(ledger) : entry.failed;
12
+ return {
13
+ toolCallId: entry.toolCallId,
14
+ label: ledgerLabel ?? entry.label,
15
+ running,
16
+ failed,
17
+ cancelled: entry.cancelled,
18
+ note: (ledger !== undefined && dispatchFailed(ledger) ? ledger.error : null) ??
19
+ entry.note,
20
+ childSessionId,
21
+ identityToken: childSessionId !== null ? subagentIdentityTokenOf(childSessionId) : null,
22
+ ordinal: entry.receipt?.ordinal ?? null,
23
+ paused: ledger !== undefined && dispatchIsPaused(ledger),
24
+ startedAt: ledger !== undefined ? ledger.created_at : null,
25
+ settledAt: ledger !== undefined && !running ? ledger.updated_at : null,
26
+ };
27
+ }
28
+ export const RESUME_SUBAGENT_TOOL_NAME = "resume_subagent";
29
+ export function demandInputOfRows(rows) {
30
+ const entries = [];
31
+ const resumeResults = [];
32
+ const deliveredOrdinals = [];
33
+ for (const row of rows) {
34
+ if (row.kind === "subagent-group") {
35
+ entries.push(...row.entries);
36
+ }
37
+ else if (row.kind === "tool-call" &&
38
+ row.toolName === RESUME_SUBAGENT_TOOL_NAME) {
39
+ resumeResults.push(row.result);
40
+ }
41
+ else if (row.kind === "subagent-delivery") {
42
+ deliveredOrdinals.push(...row.results.map((result) => result.ordinal));
43
+ }
44
+ }
45
+ return { entries, resumeResults, deliveredOrdinals };
46
+ }
47
+ export function demandInputOfMessages(messages, anchors) {
48
+ const results = new Map();
49
+ for (const message of messages) {
50
+ if (message.role === "tool" && typeof message.content === "string") {
51
+ results.set(message.toolCallId, message.content);
52
+ }
53
+ }
54
+ const calls = [];
55
+ const resumeResults = [];
56
+ for (const message of messages) {
57
+ if (message.role !== "assistant") {
58
+ continue;
59
+ }
60
+ for (const toolCall of message.toolCalls ?? []) {
61
+ const id = toolCall.id;
62
+ if (toolCall.function.name === RESUME_SUBAGENT_TOOL_NAME) {
63
+ resumeResults.push(results.get(id));
64
+ continue;
65
+ }
66
+ if (toolCall.function.name !== DISPATCH_SUBAGENT_TOOL_NAME) {
67
+ continue;
68
+ }
69
+ const failed = anchors.toolErrorAnchors.has(id);
70
+ const denied = !failed && (anchors.toolDenialAnchors?.has(id) ?? false);
71
+ const cancelled = !failed && !denied && anchors.toolCancelAnchors.has(id);
72
+ const refused = !failed && !denied && !cancelled && anchors.toolRefusalAnchors.has(id);
73
+ if (denied || refused) {
74
+ continue;
75
+ }
76
+ const result = results.get(id);
77
+ calls.push({
78
+ toolCallId: id,
79
+ settled: failed || cancelled || result !== undefined,
80
+ failed,
81
+ cancelled,
82
+ result,
83
+ errorText: undefined,
84
+ argsText: toolCall.function.arguments,
85
+ });
86
+ }
87
+ }
88
+ const entries = withSubagentGroups(calls, (call) => call, (call) => call.toolCallId).flatMap((row) => ("entries" in row ? row.entries : []));
89
+ const deliveredOrdinals = [];
90
+ for (const delivered of anchors.subagentDeliveryAnchors.values()) {
91
+ deliveredOrdinals.push(...delivered.map((result) => result.ordinal));
92
+ }
93
+ return { entries, resumeResults, deliveredOrdinals };
94
+ }
95
+ function aResumeAwaitsLedgerTruth(resumeResults, ledger) {
96
+ return resumeResults.some((result) => {
97
+ const receipt = dispatchReceiptOf(result);
98
+ if (receipt === null || receipt.outcome === "already_settled") {
99
+ return false;
100
+ }
101
+ const dispatched = ledger.get(receipt.ordinal);
102
+ return dispatched === undefined || dispatchIsRunning(dispatched);
103
+ });
104
+ }
105
+ function anySubagentStillRunning(entries, ledger) {
106
+ return entries.some((entry) => entry.receipt != null && resolvedSubagentEntryOf(entry, ledger).running);
107
+ }
108
+ export function dispatchDemandOf(input, byOrdinal) {
109
+ return {
110
+ delegated: input.entries.length > 0 ||
111
+ aResumeAwaitsLedgerTruth(input.resumeResults, EMPTY_BY_ORDINAL),
112
+ stillMoving: anySubagentStillRunning(input.entries, byOrdinal) ||
113
+ aResumeAwaitsLedgerTruth(input.resumeResults, byOrdinal),
114
+ };
115
+ }
116
+ const EMPTY_BY_ORDINAL = new Map();
117
+ export function dispatchJoinKeyOf(input) {
118
+ const ordinals = new Set();
119
+ for (const entry of input.entries) {
120
+ if (entry.receipt !== null) {
121
+ ordinals.add(entry.receipt.ordinal);
122
+ }
123
+ }
124
+ for (const result of input.resumeResults) {
125
+ const receipt = dispatchReceiptOf(result);
126
+ if (receipt !== null) {
127
+ ordinals.add(receipt.ordinal);
128
+ }
129
+ }
130
+ return [...ordinals].sort((a, b) => a - b).join(",");
131
+ }
132
+ export function staleDeliveredOrdinalsKeyOf(input, byOrdinal) {
133
+ return [...new Set(input.deliveredOrdinals)]
134
+ .filter((ordinal) => {
135
+ const ledgerRow = byOrdinal.get(ordinal);
136
+ return ledgerRow !== undefined && dispatchIsRunning(ledgerRow);
137
+ })
138
+ .sort((a, b) => a - b)
139
+ .join(",");
140
+ }
141
+ export function withDispatchLedger(rows, byOrdinal) {
142
+ if (byOrdinal.size === 0) {
143
+ return rows;
144
+ }
145
+ let out = null;
146
+ for (const [index, row] of rows.entries()) {
147
+ if (row.kind !== "subagent-group") {
148
+ continue;
149
+ }
150
+ const joined = _joinedGroupRowOf(row, byOrdinal);
151
+ if (joined !== row) {
152
+ out ??= [...rows];
153
+ out[index] = joined;
154
+ }
155
+ }
156
+ return out ?? rows;
157
+ }
158
+ function _joinedGroupRowOf(row, byOrdinal) {
159
+ let entries = null;
160
+ for (const [index, entry] of row.entries.entries()) {
161
+ const resolved = resolvedSubagentEntryOf(entry, byOrdinal);
162
+ if (resolved.running === entry.running &&
163
+ resolved.failed === entry.failed &&
164
+ resolved.note === entry.note) {
165
+ continue;
166
+ }
167
+ entries ??= [...row.entries];
168
+ entries[index] = {
169
+ ...entry,
170
+ running: resolved.running,
171
+ failed: resolved.failed,
172
+ note: resolved.note,
173
+ };
174
+ }
175
+ return entries === null ? row : { ...row, entries };
176
+ }