@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.
- package/README.md +1 -1
- package/custom-elements.json +264 -0
- package/dist/affordances/aria-dropdowns.js +315 -0
- package/dist/affordances/aria-toggles.js +39 -0
- package/dist/affordances/dropdown-display.js +129 -0
- package/dist/affordances/page-gestures.js +91 -0
- package/dist/affordances/prefill-reasons.js +75 -0
- package/dist/affordances/prefill.js +113 -62
- package/dist/appearance/theme.d.ts +138 -0
- package/dist/components/approval-card.js +3 -3
- package/dist/components/approval-context.d.ts +20 -0
- package/dist/components/assistant-companion.d.ts +15 -0
- package/dist/components/assistant-page.d.ts +61 -0
- package/dist/components/assistant-palette.d.ts +12 -0
- package/dist/components/assistant-palette.js +2 -2
- package/dist/components/child-transcript.js +1 -1
- package/dist/components/companion-header-disclosure.js +1 -1
- package/dist/components/companion-history-menu.js +1 -1
- package/dist/components/composer.js +11 -65
- package/dist/components/conversation-context.d.ts +6 -0
- package/dist/components/conversation-gate-card.js +1 -1
- package/dist/components/conversation-view.d.ts +11 -0
- package/dist/components/elicitation-context.d.ts +39 -0
- package/dist/components/model-picker-chip.js +4 -2
- package/dist/components/primitives/button.js +25 -17
- package/dist/components/primitives/floating-panel.js +1 -1
- package/dist/components/provider-chip.js +8 -1
- package/dist/components/question-panel-footer.js +1 -1
- package/dist/components/react-tool-view.d.ts +7 -0
- package/dist/components/subagent-count-pill.js +2 -2
- package/dist/components/subagent-group-row.js +1 -26
- package/dist/components/subagent-preview-popover.js +1 -1
- package/dist/components/subscription-connect-arms.js +6 -4
- package/dist/components/subscription-connect-flow.js +30 -45
- package/dist/components/subscription-connected-standing.js +9 -6
- package/dist/components/subscription-plan-notice.js +4 -2
- package/dist/components/teaflask-assistant-provider.d.ts +99 -0
- package/dist/components/teaflask-assistant.d.ts +33 -0
- package/dist/components/tool-views/action-view.js +1 -1
- package/dist/components/tool-views/parts-classes.d.ts +5 -5
- package/dist/components/tool-views/parts-classes.js +5 -5
- package/dist/components/tool-views/parts.d.ts +44 -0
- package/dist/components/tool-views/questions-view.js +2 -2
- package/dist/components/tool-views/view-dom.d.ts +76 -0
- package/dist/components/transcript.js +2 -2
- package/dist/components/use-assistant-activity.d.ts +5 -0
- package/dist/components/use-assistant-conversation.d.ts +99 -2
- package/dist/components/use-store-cell.d.ts +5 -0
- package/dist/components/use-thread-dispatches.js +8 -366
- package/dist/components/use-transcript-folds.js +2 -1
- package/dist/components/use-transcript.d.ts +55 -2
- package/dist/components/use-transcript.js +7 -2
- package/dist/contract/actions-adapter.d.ts +78 -0
- package/dist/contract/errors.d.ts +6 -1
- package/dist/contract/events.d.ts +1 -3
- package/dist/contract/identity.d.ts +1 -1
- package/dist/contract/subscriptions.d.ts +2 -2
- package/dist/contract/subscriptions.js +1 -1
- package/dist/contract/telemetry.d.ts +45 -0
- package/dist/contract/threads.d.ts +5 -1
- package/dist/core/activity.d.ts +44 -0
- package/dist/core/approval-inbox.d.ts +69 -0
- package/dist/core/assistant-session-registry.js +15 -0
- package/dist/core/composer-attachments.js +82 -0
- package/dist/core/composer-input-state.js +1 -0
- package/dist/core/composer-policy.d.ts +20 -0
- package/dist/core/connection-epoch.d.ts +65 -2
- package/dist/core/conversation-adoption.js +3 -0
- package/dist/core/conversation-contract.d.ts +112 -1
- package/dist/core/conversation-publish.js +1 -0
- package/dist/core/conversation-store.d.ts +3 -0
- package/dist/core/conversation-store.js +7 -0
- package/dist/core/dispatch-poll.js +81 -0
- package/dist/core/elicitation-answers.js +12 -0
- package/dist/core/elicitation-cards.d.ts +14 -0
- package/dist/core/elicitation-pickers.d.ts +16 -0
- package/dist/core/execution-handlers.js +3 -3
- package/dist/core/memory-provenance-anchors.d.ts +16 -0
- package/dist/core/observable-cell.d.ts +12 -0
- package/dist/core/pending-decision-gap.d.ts +9 -0
- package/dist/core/question-drafts.d.ts +59 -0
- package/dist/core/receipt-anchors.d.ts +9 -0
- package/dist/core/segment-timing.d.ts +23 -0
- package/dist/core/subagent-delivery-anchors.d.ts +7 -0
- package/dist/core/subagent-ledger-join.js +176 -0
- package/dist/core/subagent-rows.d.ts +68 -0
- package/dist/core/thread-dispatch-ledger.js +303 -0
- package/dist/core/tool-call-display.d.ts +71 -0
- package/dist/core/tool-call-presentation.d.ts +34 -1
- package/dist/core/tool-call-presentation.js +0 -1
- package/dist/core/tool-schema-anchors.d.ts +6 -0
- package/dist/core/tool-view.d.ts +174 -1
- package/dist/core/transcript-rows.d.ts +138 -3
- package/dist/core/turn-failed-anchors.d.ts +4 -0
- package/dist/core/user-turn-ledger.d.ts +3 -0
- package/dist/generated/models/apiErrorCode.d.ts +1 -0
- package/dist/generated/models/apiErrorCode.js +1 -0
- package/dist/generated/models/assistantTurnStatus.d.ts +16 -0
- package/dist/generated/models/servingAssistantThreadResponse.d.ts +23 -0
- package/dist/generated/models/servingAttachmentResponse.d.ts +29 -0
- package/dist/generated/models/servingErrorCode.d.ts +18 -0
- package/dist/generated/models/servingTurnAttachmentResponse.d.ts +12 -0
- package/dist/generated/models/siteTheme.d.ts +1 -0
- package/dist/generated/models/thinkingEffort.d.ts +10 -0
- package/dist/generated/models/threadModelPickResponse.d.ts +12 -0
- package/dist/headless.d.ts +9 -4
- package/dist/index.d.ts +2 -6
- package/dist/index.js +0 -3
- package/dist/persistence/stored-thread.d.ts +5 -0
- package/dist/reader/render.js +7 -4
- package/dist/reader/roles.js +28 -1
- package/dist/reader/snapshot-node.js +2 -29
- package/dist/reader/snapshot-root.js +14 -8
- package/dist/reader/snapshot.js +6 -1
- package/dist/styles.css +1 -1
- package/dist/transport/serving-error.d.ts +21 -0
- package/package.json +6 -25
- package/dist/affordances/highlight.d.ts +0 -3
- package/dist/affordances/prefill.d.ts +0 -14
- package/dist/components/activity-rail.d.ts +0 -12
- package/dist/components/activity-shelf.d.ts +0 -7
- package/dist/components/agent-identity-mark.d.ts +0 -7
- package/dist/components/appearance-context.d.ts +0 -14
- package/dist/components/approval-card.d.ts +0 -7
- package/dist/components/assistant-palette-body.d.ts +0 -3
- package/dist/components/assistant-transcript.d.ts +0 -47
- package/dist/components/attachment-chips.d.ts +0 -4
- package/dist/components/child-transcript.d.ts +0 -22
- package/dist/components/companion-drawer-body.d.ts +0 -1
- package/dist/components/companion-drawer.d.ts +0 -10
- package/dist/components/companion-header-disclosure.d.ts +0 -20
- package/dist/components/companion-history-menu.d.ts +0 -15
- package/dist/components/companion-mark-image.d.ts +0 -3
- package/dist/components/companion-mark-image.js +0 -18
- package/dist/components/companion-mark.d.ts +0 -1
- package/dist/components/companion-mode-menu.d.ts +0 -15
- package/dist/components/composer-attachment-chip.d.ts +0 -7
- package/dist/components/composer-banner.d.ts +0 -4
- package/dist/components/composer.d.ts +0 -4
- package/dist/components/conversation-gate-card.d.ts +0 -8
- package/dist/components/conversation-surfaces-provider.d.ts +0 -6
- package/dist/components/copy-text-button.d.ts +0 -5
- package/dist/components/elicitation-receipt-row.d.ts +0 -4
- package/dist/components/human-file-size.d.ts +0 -1
- package/dist/components/icons.d.ts +0 -15
- package/dist/components/lazy-body.d.ts +0 -4
- package/dist/components/markdown/assistant-markdown.d.ts +0 -3
- package/dist/components/markdown/code-block.d.ts +0 -4
- package/dist/components/markdown/highlight.d.ts +0 -1
- package/dist/components/markdown/markdown-structure.d.ts +0 -16
- package/dist/components/markdown/memoized-blocks.d.ts +0 -6
- package/dist/components/markdown/paced-assistant-markdown.d.ts +0 -4
- package/dist/components/markdown/reveal-pacer.d.ts +0 -20
- package/dist/components/markdown/shiki-highlighter.d.ts +0 -1
- package/dist/components/markdown/streaming-repair.d.ts +0 -1
- package/dist/components/markdown/use-highlighted-html.d.ts +0 -1
- package/dist/components/markdown/use-paced-reveal.d.ts +0 -5
- package/dist/components/memory-updated-footer.d.ts +0 -4
- package/dist/components/message-list-row.d.ts +0 -13
- package/dist/components/message-list-slots.d.ts +0 -25
- package/dist/components/message-list-slots.js +0 -1
- package/dist/components/message-list.d.ts +0 -23
- package/dist/components/model-picker-chip.d.ts +0 -1
- package/dist/components/model-picker-effort.d.ts +0 -4
- package/dist/components/model-picker-panels.d.ts +0 -22
- package/dist/components/notice-banner.d.ts +0 -8
- package/dist/components/operation-icons.d.ts +0 -19
- package/dist/components/pretty-print.d.ts +0 -1
- package/dist/components/primitives/autofocus.d.ts +0 -1
- package/dist/components/primitives/button.d.ts +0 -10
- package/dist/components/primitives/cx.d.ts +0 -1
- package/dist/components/primitives/dialog.d.ts +0 -7
- package/dist/components/primitives/disclosure.d.ts +0 -22
- package/dist/components/primitives/file-input.d.ts +0 -5
- package/dist/components/primitives/floating-panel.d.ts +0 -15
- package/dist/components/primitives/kbd.d.ts +0 -2
- package/dist/components/primitives/sheet.d.ts +0 -11
- package/dist/components/primitives/sheet.js +0 -18
- package/dist/components/primitives/textarea.d.ts +0 -7
- package/dist/components/primitives/use-dock-reflow.d.ts +0 -2
- package/dist/components/primitives/use-swipe-dismiss.d.ts +0 -17
- package/dist/components/provider-chip.d.ts +0 -8
- package/dist/components/question-panel-answers.d.ts +0 -29
- package/dist/components/question-panel-footer.d.ts +0 -9
- package/dist/components/question-panel.d.ts +0 -4
- package/dist/components/reasoning-row.d.ts +0 -4
- package/dist/components/receipt-rows.d.ts +0 -3
- package/dist/components/run-status-announcer.d.ts +0 -5
- package/dist/components/scroll-follow-guards.d.ts +0 -1
- package/dist/components/served-suggestions.d.ts +0 -3
- package/dist/components/slot-boundary.d.ts +0 -11
- package/dist/components/standing-poll.d.ts +0 -1
- package/dist/components/streaming-states.d.ts +0 -12
- package/dist/components/subagent-count-pill.d.ts +0 -8
- package/dist/components/subagent-current-work.d.ts +0 -6
- package/dist/components/subagent-delegation-surface.d.ts +0 -9
- package/dist/components/subagent-delivery-divider.d.ts +0 -5
- package/dist/components/subagent-drill-in.d.ts +0 -8
- package/dist/components/subagent-execution-work.d.ts +0 -3
- package/dist/components/subagent-group-row.d.ts +0 -26
- package/dist/components/subagent-preview-popover.d.ts +0 -8
- package/dist/components/subscription-connect-arms.d.ts +0 -25
- package/dist/components/subscription-connect-flow.d.ts +0 -60
- package/dist/components/subscription-connected-standing.d.ts +0 -16
- package/dist/components/subscription-plan-notice.d.ts +0 -1
- package/dist/components/subscription-recheck.d.ts +0 -10
- package/dist/components/surface-boundary.d.ts +0 -8
- package/dist/components/suspension-surfaces.d.ts +0 -3
- package/dist/components/thread-list.d.ts +0 -16
- package/dist/components/tool-arguments-summary.d.ts +0 -2
- package/dist/components/tool-call-rows.d.ts +0 -10
- package/dist/components/tool-row.d.ts +0 -7
- package/dist/components/tool-view-registry-context.d.ts +0 -3
- package/dist/components/tool-view-slot.d.ts +0 -11
- package/dist/components/tool-views/action-view.d.ts +0 -1
- package/dist/components/tool-views/command-view.d.ts +0 -1
- package/dist/components/tool-views/docs-search-view.d.ts +0 -10
- package/dist/components/tool-views/file-edit-view.d.ts +0 -1
- package/dist/components/tool-views/questions-view.d.ts +0 -1
- package/dist/components/transcript.d.ts +0 -3
- package/dist/components/use-agent-subscriber.d.ts +0 -3
- package/dist/components/use-agent-subscriber.js +0 -13
- package/dist/components/use-answer-list-fold.d.ts +0 -6
- package/dist/components/use-assistant-surface-presence.d.ts +0 -2
- package/dist/components/use-child-replay-stream.d.ts +0 -20
- package/dist/components/use-latest-ref.d.ts +0 -2
- package/dist/components/use-member-toggle-outrank.d.ts +0 -6
- package/dist/components/use-perch-clearance.d.ts +0 -2
- package/dist/components/use-question-panel-keys.d.ts +0 -32
- package/dist/components/use-register-assistant-surface.d.ts +0 -2
- package/dist/components/use-resolved-theme-mode.d.ts +0 -3
- package/dist/components/use-roster-disclosure.d.ts +0 -20
- package/dist/components/use-roster-preview.d.ts +0 -24
- package/dist/components/use-thread-dispatches.d.ts +0 -8
- package/dist/components/use-transcript-folds.d.ts +0 -26
- package/dist/components/user-message.d.ts +0 -6
- package/dist/contract/actions-adapter.js +0 -1
- package/dist/contract/assistant-config.js +0 -1
- package/dist/contract/dispatches.d.ts +0 -15
- package/dist/contract/errors.js +0 -1
- package/dist/contract/identity.js +0 -1
- package/dist/core/activity-title.d.ts +0 -1
- package/dist/core/agent-identity.d.ts +0 -2
- package/dist/core/approval-decision.d.ts +0 -6
- package/dist/core/approval-resolved.d.ts +0 -7
- package/dist/core/assistant-prose.d.ts +0 -2
- package/dist/core/assistant-session-registry.d.ts +0 -51
- package/dist/core/attachment-uploads.d.ts +0 -5
- package/dist/core/block-timing-anchors.d.ts +0 -5
- package/dist/core/companion-drawer-flag.d.ts +0 -4
- package/dist/core/companion-presence.d.ts +0 -7
- package/dist/core/composer-input-state.d.ts +0 -8
- package/dist/core/connection-driver.d.ts +0 -3
- package/dist/core/conversation-adoption.d.ts +0 -13
- package/dist/core/conversation-contract.js +0 -1
- package/dist/core/conversation-publish.d.ts +0 -8
- package/dist/core/conversation-refresh.d.ts +0 -4
- package/dist/core/conversation-send.d.ts +0 -6
- package/dist/core/disposable-subscriber.d.ts +0 -6
- package/dist/core/disposable-subscriber.js +0 -18
- package/dist/core/dock-reflow.d.ts +0 -5
- package/dist/core/elicitation-answers.d.ts +0 -7
- package/dist/core/epoch-sync.d.ts +0 -12
- package/dist/core/error-copy.d.ts +0 -3
- package/dist/core/execution-driver.d.ts +0 -37
- package/dist/core/host-fill.d.ts +0 -1
- package/dist/core/hotkey.d.ts +0 -18
- package/dist/core/identity-pair.d.ts +0 -14
- package/dist/core/idle-recheck.d.ts +0 -3
- package/dist/core/messages-cell.d.ts +0 -11
- package/dist/core/perch-clearance.d.ts +0 -19
- package/dist/core/question-receipt.d.ts +0 -11
- package/dist/core/reasoning-copy.d.ts +0 -2
- package/dist/core/run-folds.d.ts +0 -43
- package/dist/core/run-status.d.ts +0 -4
- package/dist/core/settle-refresh.d.ts +0 -9
- package/dist/core/step-caption.d.ts +0 -2
- package/dist/core/stop-copy.d.ts +0 -1
- package/dist/core/stop-settle.d.ts +0 -5
- package/dist/core/stream-trouble.d.ts +0 -5
- package/dist/core/subagent-brief.d.ts +0 -3
- package/dist/core/subagent-presence.d.ts +0 -10
- package/dist/core/subagent-roster.d.ts +0 -35
- package/dist/core/surface-registry.d.ts +0 -16
- package/dist/core/suspension-queue.d.ts +0 -14
- package/dist/core/tail-slot-pool.d.ts +0 -13
- package/dist/core/time-labels.d.ts +0 -7
- package/dist/core/tool-call-display-anchors.d.ts +0 -11
- package/dist/core/tool-cancel-anchors.d.ts +0 -5
- package/dist/core/tool-decision-anchors.d.ts +0 -6
- package/dist/core/tool-error-anchors.d.ts +0 -5
- package/dist/core/tool-flag-anchors.d.ts +0 -9
- package/dist/core/tool-offload-anchors.d.ts +0 -5
- package/dist/core/tool-outcome.d.ts +0 -9
- package/dist/core/tool-refusal-anchors.d.ts +0 -5
- package/dist/core/tool-result-envelope.d.ts +0 -3
- package/dist/core/tool-sentence-anchors.d.ts +0 -11
- package/dist/core/transcript-lease.d.ts +0 -2
- package/dist/core/turn-failure-copy.d.ts +0 -4
- package/dist/core/turns-backfill.d.ts +0 -14
- package/dist/core/wire-sentence-cap.d.ts +0 -1
- package/dist/generated/serving.d.ts +0 -38
- package/dist/markdown.d.ts +0 -4
- package/dist/markdown.js +0 -4
- package/dist/persistence/execution-ledger.d.ts +0 -7
- package/dist/persistence/panel-mode.d.ts +0 -6
- package/dist/persistence/plan-notice.d.ts +0 -3
- package/dist/reader/accessible-name.d.ts +0 -3
- package/dist/reader/interactivity.d.ts +0 -11
- package/dist/reader/layout-probe.d.ts +0 -29
- package/dist/reader/line-diff.d.ts +0 -1
- package/dist/reader/read-page.d.ts +0 -12
- package/dist/reader/redaction.d.ts +0 -3
- package/dist/reader/render.d.ts +0 -3
- package/dist/reader/roles.d.ts +0 -8
- package/dist/reader/snapshot-compaction.d.ts +0 -5
- package/dist/reader/snapshot-node.d.ts +0 -4
- package/dist/reader/snapshot-root.d.ts +0 -15
- package/dist/reader/snapshot.d.ts +0 -60
- package/dist/reader/visibility.d.ts +0 -8
- package/dist/scroll.d.ts +0 -1
- package/dist/scroll.js +0 -1
- package/dist/transcript-ui.d.ts +0 -15
- package/dist/transcript-ui.js +0 -8
- package/dist/transcript.d.ts +0 -43
- package/dist/transcript.js +0 -38
- package/dist/transport/actions-adapter.d.ts +0 -4
- package/dist/transport/door-budget.d.ts +0 -4
- package/dist/transport/serving-api.d.ts +0 -33
- 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) =>
|
|
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
|
+
}
|