@teaflask/assistant 0.6.0 → 0.7.0
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/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/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/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
|
@@ -47,7 +47,7 @@ export function HeaderDisclosureMenu({ id, onClose, triggerRef, triggerId, "aria
|
|
|
47
47
|
menuRef.current?.querySelector("button")?.focus();
|
|
48
48
|
}
|
|
49
49
|
}, [autoFocusFirstButton]);
|
|
50
|
-
return (_jsx("div", { ref: menuRef, id: id, role: "dialog", "aria-label": ariaLabel, "data-tf-glass": "", "data-tf-disclosure": "", "data-tf-surface-inset": insetFromSurfaceTop ? "" : undefined, className: cx("tf:absolute tf:top-14 tf:flex tf:max-h-96 tf:flex-col tf:overflow-hidden tf:rounded-2xl tf:border", className), onKeyDown: (event) => {
|
|
50
|
+
return (_jsx("div", { ref: menuRef, id: id, role: "dialog", "aria-label": ariaLabel, "data-tf-glass": "", "data-tf-popover": "", "data-tf-disclosure": "", "data-tf-surface-inset": insetFromSurfaceTop ? "" : undefined, className: cx("tf:absolute tf:top-14 tf:flex tf:max-h-96 tf:flex-col tf:overflow-hidden tf:rounded-2xl tf:border", className), onKeyDown: (event) => {
|
|
51
51
|
if (event.key !== "Escape") {
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
@@ -11,7 +11,7 @@ export function CompanionHeaderTitle({ menuId, open, onOpenChange, triggerRef, f
|
|
|
11
11
|
if (!core.historyExpected) {
|
|
12
12
|
return (_jsx("h2", { className: "tf:min-w-0 tf:flex-1 tf:truncate tf:text-tf-label tf:font-medium tf:text-tf-muted-foreground", children: title }));
|
|
13
13
|
}
|
|
14
|
-
return (_jsx("h2", { className: "tf:flex tf:min-w-0 tf:flex-1 tf:items-center tf:text-tf-label tf:font-medium tf:text-tf-muted-foreground", children: _jsxs(HeaderDisclosureTrigger, { menuId: menuId, open: open, onOpenChange: onOpenChange, triggerRef: triggerRef, variant: "bare", className: "tf:-ml-1.5 tf:min-w-0 tf:px-1.5 tf:py-1 tf:hover:bg-tf-accent tf:hover:text-tf-foreground", children: [_jsx("span", { className: "tf:min-w-0 tf:truncate", children: title }), _jsx(ChevronDownIcon, {})] }) }));
|
|
14
|
+
return (_jsx("h2", { className: "tf:flex tf:min-w-0 tf:flex-1 tf:items-center tf:text-tf-label tf:font-medium tf:text-tf-muted-foreground", children: _jsxs(HeaderDisclosureTrigger, { menuId: menuId, open: open, onOpenChange: onOpenChange, triggerRef: triggerRef, variant: "bare", className: "tf:-ml-1.5 tf:min-w-0 tf:px-1.5 tf:py-1 tf:hover:bg-tf-accent tf:hover:text-tf-accent-foreground", children: [_jsx("span", { className: "tf:min-w-0 tf:truncate", children: title }), _jsx(ChevronDownIcon, {})] }) }));
|
|
15
15
|
}
|
|
16
16
|
export function CompanionHistoryMenu({ id, onClose, triggerRef, triggerId, insetFromSurfaceTop, }) {
|
|
17
17
|
const core = useAssistantConversation();
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useEffect, useLayoutEffect, useRef, useState, } from "react";
|
|
4
|
-
import {
|
|
5
|
-
import { humanFileSize } from "./human-file-size.js";
|
|
4
|
+
import { ASSISTANT_MESSAGE_MAX_CHARS, } from "../contract/threads.js";
|
|
6
5
|
import { attachmentAcceptOf, ComposerAttachmentChip, } from "./composer-attachment-chip.js";
|
|
7
6
|
import { ComposerBanner } from "./composer-banner.js";
|
|
8
7
|
import { useConversation } from "./conversation-context.js";
|
|
@@ -13,14 +12,15 @@ import { TfTextarea } from "./primitives/textarea.js";
|
|
|
13
12
|
import { ModelPickerShelf } from "./model-picker-chip.js";
|
|
14
13
|
import { useOptionalAssistantSession } from "./teaflask-assistant-provider.js";
|
|
15
14
|
import { NO_GATE } from "../core/connect-gate.js";
|
|
16
|
-
import {
|
|
15
|
+
import { attachmentRoomOf } from "../core/composer-attachments.js";
|
|
16
|
+
import { attachmentDraftFailed, capSlotsSpentBy, CHARACTER_COUNT_VISIBLE_FROM, composerKeyHandlersOf, } from "../core/composer-policy.js";
|
|
17
17
|
import { ObservableCell } from "../core/observable-cell.js";
|
|
18
18
|
import { useCell } from "./use-store-cell.js";
|
|
19
19
|
const NO_POLICY = new ObservableCell(null);
|
|
20
20
|
const NO_GATE_CELL = new ObservableCell(NO_GATE);
|
|
21
21
|
const COMPOSER_MAX_HEIGHT_PX = 200;
|
|
22
22
|
export function Composer({ compact = false, surface = "page", }) {
|
|
23
|
-
const { busy, pendingSend, sendMessage, composerRefocusPending, markComposerRefocusHandled, stopping, stopTurn, composerInput, setDraft, setAttachments, noteComposerFocus, takeComposerCaretReturn, } = useConversation();
|
|
23
|
+
const { busy, pendingSend, sendMessage, composerRefocusPending, markComposerRefocusHandled, stopping, stopTurn, composerInput, setDraft, setAttachments, addFiles, noteComposerFocus, takeComposerCaretReturn, } = useConversation();
|
|
24
24
|
const { draft, attachments } = useCell(composerInput);
|
|
25
25
|
const session = useOptionalAssistantSession();
|
|
26
26
|
const policy = useCell(session?.attachmentPolicy ?? NO_POLICY);
|
|
@@ -37,7 +37,7 @@ export function Composer({ compact = false, surface = "page", }) {
|
|
|
37
37
|
const attach = useComposerAttachments({
|
|
38
38
|
session,
|
|
39
39
|
policy,
|
|
40
|
-
|
|
40
|
+
addFiles,
|
|
41
41
|
setAttachments,
|
|
42
42
|
});
|
|
43
43
|
const { textareaRef, onTextareaFocus, onTextareaBlur } = useComposerFocus({
|
|
@@ -96,74 +96,20 @@ function useComposerSend({ busy, draft, attachments, composerInput, sendMessage,
|
|
|
96
96
|
}
|
|
97
97
|
return { sending, sendDisabled, submitDraft };
|
|
98
98
|
}
|
|
99
|
-
function useComposerAttachments({ session, policy,
|
|
99
|
+
function useComposerAttachments({ session, policy, addFiles, setAttachments, }) {
|
|
100
100
|
useEffect(() => {
|
|
101
101
|
session?.ensureAssistantConfig();
|
|
102
102
|
}, [session]);
|
|
103
|
-
function
|
|
104
|
-
if (files
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
const { store } = session;
|
|
108
|
-
const room = Math.min(policy.max_per_message, ASSISTANT_MAX_ATTACHMENTS);
|
|
109
|
-
let taken = capSlotsSpentBy(attachments);
|
|
110
|
-
for (const file of Array.from(files)) {
|
|
111
|
-
const localId = mintAttachmentDraftId();
|
|
112
|
-
const entry = {
|
|
113
|
-
localId,
|
|
114
|
-
filename: file.name !== "" ? file.name : "attachment",
|
|
115
|
-
byteSize: file.size,
|
|
116
|
-
status: "uploading",
|
|
117
|
-
};
|
|
118
|
-
if (taken >= room) {
|
|
119
|
-
setAttachments((current) => [
|
|
120
|
-
...current,
|
|
121
|
-
{
|
|
122
|
-
...entry,
|
|
123
|
-
status: "failed",
|
|
124
|
-
error: `Too many files — the limit is ${String(room)} per message.`,
|
|
125
|
-
},
|
|
126
|
-
]);
|
|
127
|
-
continue;
|
|
128
|
-
}
|
|
129
|
-
const cap = pickCapOf(file, policy.max_bytes_by_kind);
|
|
130
|
-
if (file.size > cap.bytes) {
|
|
131
|
-
setAttachments((current) => [
|
|
132
|
-
...current,
|
|
133
|
-
{
|
|
134
|
-
...entry,
|
|
135
|
-
status: "failed",
|
|
136
|
-
error: `Too large — the limit for ${cap.label} is ${humanFileSize(cap.bytes)}.`,
|
|
137
|
-
},
|
|
138
|
-
]);
|
|
139
|
-
continue;
|
|
140
|
-
}
|
|
141
|
-
taken += 1;
|
|
142
|
-
setAttachments((current) => [...current, entry]);
|
|
143
|
-
store.uploadAttachment(file).then((settled) => {
|
|
144
|
-
setAttachments((current) => current.map((item) => item.localId === localId
|
|
145
|
-
? { ...item, status: "ready", attachment: settled }
|
|
146
|
-
: item));
|
|
147
|
-
}, (error) => {
|
|
148
|
-
setAttachments((current) => current.map((item) => item.localId === localId
|
|
149
|
-
? {
|
|
150
|
-
...item,
|
|
151
|
-
status: "failed",
|
|
152
|
-
error: error instanceof Error
|
|
153
|
-
? error.message
|
|
154
|
-
: "The upload failed.",
|
|
155
|
-
}
|
|
156
|
-
: item));
|
|
157
|
-
});
|
|
103
|
+
function pickFiles(files) {
|
|
104
|
+
if (files !== null) {
|
|
105
|
+
void addFiles(files);
|
|
158
106
|
}
|
|
159
107
|
}
|
|
160
108
|
function removeAttachment(localId) {
|
|
161
109
|
setAttachments((current) => current.filter((item) => item.localId !== localId));
|
|
162
110
|
}
|
|
163
|
-
const attachmentRoom = policy === null
|
|
164
|
-
|
|
165
|
-
: Math.min(policy.max_per_message, ASSISTANT_MAX_ATTACHMENTS);
|
|
166
|
-
return { attachmentRoom, addFiles, removeAttachment };
|
|
111
|
+
const attachmentRoom = policy === null ? 0 : attachmentRoomOf(policy);
|
|
112
|
+
return { attachmentRoom, addFiles: pickFiles, removeAttachment };
|
|
167
113
|
}
|
|
168
114
|
function useComposerFocus({ surface, draft, busy, composerRefocusPending, markComposerRefocusHandled, noteComposerFocus, takeComposerCaretReturn, }) {
|
|
169
115
|
const textareaRef = useRef(null);
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import type { ComposerContract } from "../core/conversation-store.js";
|
|
2
2
|
export type { ComposerContract };
|
|
3
3
|
export declare const ConversationContext: import("react").Context<ComposerContract | null>;
|
|
4
|
+
/**
|
|
5
|
+
* Returns the live message-box state and controls for the open conversation
|
|
6
|
+
* (busy and stopping flags, the draft, `sendMessage`, `stopTurn`), for building
|
|
7
|
+
* your own composer or send buttons. It must be called inside the provider
|
|
8
|
+
* (from either entry point) and throws otherwise.
|
|
9
|
+
*/
|
|
4
10
|
export declare function useConversation(): ComposerContract;
|
|
@@ -34,7 +34,7 @@ function ConnectBannerRow({ status, gate, refresh, }) {
|
|
|
34
34
|
session.notePlanSignedIn(status.provider);
|
|
35
35
|
});
|
|
36
36
|
if (connect.flow.kind !== "idle") {
|
|
37
|
-
return (_jsx(ConnectFlow, { name: name, flow: connect.flow, errorSentence: connect.errorSentence, onBegin: connect.begin, onCancel: connect.cancel
|
|
37
|
+
return (_jsx(ConnectFlow, { name: name, flow: connect.flow, errorSentence: connect.errorSentence, onBegin: connect.begin, onCancel: connect.cancel }));
|
|
38
38
|
}
|
|
39
39
|
const taster = gate.reason === "taster_exhausted";
|
|
40
40
|
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "tf:flex tf:flex-wrap tf:items-center tf:gap-x-3 tf:gap-y-2", children: [_jsxs("p", { className: "tf:m-0 tf:flex tf:min-w-56 tf:flex-1 tf:items-center tf:gap-2 tf:text-tf-label tf:text-tf-foreground", children: [_jsx(OpenAiMarkIcon, {}), taster
|
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
2
|
import type { AssistantConversation } from "./use-assistant-conversation.js";
|
|
3
|
+
/**
|
|
4
|
+
* The icon for an opening prompt. `"ask"` shows a magnifying glass, `"review"`
|
|
5
|
+
* a flag, `"write"` a pencil and `"learn"` a book.
|
|
6
|
+
*/
|
|
3
7
|
export type AssistantSuggestionKind = "ask" | "review" | "write" | "learn";
|
|
8
|
+
/** An opening prompt, with the icon shown beside it. */
|
|
4
9
|
export interface AssistantSuggestion {
|
|
10
|
+
/** The text shown and, when clicked, sent as the user's message. */
|
|
5
11
|
prompt: string;
|
|
12
|
+
/** Which icon the prompt shows, and the default is `"ask"`. */
|
|
6
13
|
kind?: AssistantSuggestionKind;
|
|
7
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* An opening prompt, given as plain text (shown with the `"ask"` icon) or as an
|
|
17
|
+
* object with a `kind`.
|
|
18
|
+
*/
|
|
8
19
|
export type AssistantSuggestionInput = string | AssistantSuggestion;
|
|
9
20
|
export declare function ConversationView({ core, surface, suggestions, welcomeTitle, welcomeMark, }: {
|
|
10
21
|
core: AssistantConversation;
|
|
@@ -1,14 +1,53 @@
|
|
|
1
1
|
import type { ElicitationCardModel, QuestionSetCardModel } from "../core/elicitation-cards.js";
|
|
2
2
|
import { QuestionDraftStore } from "../core/question-drafts.js";
|
|
3
|
+
/**
|
|
4
|
+
* The question sets to show, how to answer or dismiss them, and their unsent
|
|
5
|
+
* answers, as returned by useElicitations().
|
|
6
|
+
*/
|
|
3
7
|
export interface ElicitationSurface {
|
|
8
|
+
/**
|
|
9
|
+
* Question sets the agent has asked in the open conversation. Sets already
|
|
10
|
+
* answered or no longer answerable can stay in the list for a while, so
|
|
11
|
+
* render by each card's status.
|
|
12
|
+
*/
|
|
4
13
|
cards: readonly ElicitationCardModel[];
|
|
14
|
+
/**
|
|
15
|
+
* Sends answers to a whole question set in one request, exactly one { id,
|
|
16
|
+
* text } per question, each text at most 1,900 characters. It does not
|
|
17
|
+
* reject: on a server error or while the conversation is disconnected the
|
|
18
|
+
* card's errorSentence explains it, the card stays answerable and the draft
|
|
19
|
+
* is kept; on success the set's draft is cleared; a set that was already
|
|
20
|
+
* answered elsewhere or has expired turns stale instead (it can no longer
|
|
21
|
+
* be answered), and its draft goes with it. Repeat submits while one is in
|
|
22
|
+
* flight are ignored.
|
|
23
|
+
*/
|
|
5
24
|
submitQuestionAnswers: (card: QuestionSetCardModel, answers: readonly {
|
|
6
25
|
id: string;
|
|
7
26
|
text: string;
|
|
8
27
|
}[]) => Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Dismisses a whole question set without answering: the agent is told the
|
|
30
|
+
* visitor declined and carries on without asking the same questions again.
|
|
31
|
+
* Like submitQuestionAnswers it does not reject. While the conversation is
|
|
32
|
+
* disconnected, or on a server error, nothing is dismissed and the card's
|
|
33
|
+
* errorSentence says so. On success the set's draft is cleared; a set
|
|
34
|
+
* already answered elsewhere or expired turns stale instead, and its draft
|
|
35
|
+
* goes with it. Repeat requests while one is in flight are ignored.
|
|
36
|
+
*/
|
|
9
37
|
cancelQuestionSet: (card: QuestionSetCardModel) => Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* The visitor's unsent answers, kept outside your components so remounts
|
|
40
|
+
* and reconnects don't lose them. In memory only, so a page reload discards
|
|
41
|
+
* them.
|
|
42
|
+
*/
|
|
10
43
|
drafts: QuestionDraftStore;
|
|
11
44
|
}
|
|
12
45
|
export declare const ElicitationsContext: import("react").Context<ElicitationSurface>;
|
|
46
|
+
/**
|
|
47
|
+
* Returns the questions the agent is asking the visitor, the functions that
|
|
48
|
+
* answer or dismiss them, and the store of unsent answers. Live inside
|
|
49
|
+
* <TeaflaskAssistantProvider>; outside it the list is empty and submitting or
|
|
50
|
+
* cancelling rejects with an error.
|
|
51
|
+
*/
|
|
13
52
|
export declare function useElicitations(): ElicitationSurface;
|
|
14
53
|
export declare function anchoredElicitationsFor(cards: readonly ElicitationCardModel[], toolCallId: string): ElicitationCardModel[];
|
|
@@ -56,7 +56,9 @@ function MountedModelPickerShelf() {
|
|
|
56
56
|
}
|
|
57
57
|
return (_jsxs("div", { className: "tf:relative tf:mt-1.5 tf:flex tf:items-center tf:justify-end tf:gap-2 tf:px-1", children: [ownsAccountChip ? (_jsx(ProviderChip, { statuses: connectable, open: openChip === "account", onOpenChange: (next) => {
|
|
58
58
|
setOpenChip(next ? "account" : null);
|
|
59
|
-
}, fundingNote:
|
|
59
|
+
}, fundingNote: connectable.some((status) => status.offered)
|
|
60
|
+
? "Models your plan serves run on it; other picks run on this site's own funding."
|
|
61
|
+
: undefined })) : null, _jsx(ModelPickerChip, { menu: menu, open: openChip === "picker", onOpenChange: (next) => {
|
|
60
62
|
setOpenChip(next ? "picker" : null);
|
|
61
63
|
} })] }));
|
|
62
64
|
}
|
|
@@ -64,7 +66,7 @@ function ModelPickerChip({ menu, open, onOpenChange, }) {
|
|
|
64
66
|
const { modelPick, setModelPick } = useConversation();
|
|
65
67
|
const { panel, setPanel, showPanel, triggerRef, menuRef, rootPanelRef, modelPanelRef, effortPanelRef, } = useModelPickerPanels({ open, onOpenChange });
|
|
66
68
|
const { currentModelId, renderedLadder, currentEffort, currentName } = pickerSelectionOf(menu, modelPick);
|
|
67
|
-
return (_jsxs(_Fragment, { children: [_jsx(ModelPickerTrigger, { triggerRef: triggerRef, open: open, onOpenChange: onOpenChange, setPanel: setPanel, currentName: currentName, currentEffort: currentEffort }), open ? (_jsxs("div", { ref: menuRef, id: "tf-model-picker-menu", role: "dialog", "aria-label": "Choose model and effort", "data-tf-glass": "", className: "tf:absolute tf:right-0 tf:bottom-full tf:mb-2 tf:flex tf:max-h-[min(32rem,calc(100vh-6rem))] tf:w-80 tf:max-w-full tf:flex-col tf:overflow-y-auto tf:rounded-2xl tf:border tf:p-2", onKeyDown: (event) => {
|
|
69
|
+
return (_jsxs(_Fragment, { children: [_jsx(ModelPickerTrigger, { triggerRef: triggerRef, open: open, onOpenChange: onOpenChange, setPanel: setPanel, currentName: currentName, currentEffort: currentEffort }), open ? (_jsxs("div", { ref: menuRef, id: "tf-model-picker-menu", role: "dialog", "aria-label": "Choose model and effort", "data-tf-glass": "", "data-tf-popover": "", className: "tf:absolute tf:right-0 tf:bottom-full tf:mb-2 tf:flex tf:max-h-[min(32rem,calc(100vh-6rem))] tf:w-80 tf:max-w-full tf:flex-col tf:overflow-y-auto tf:rounded-2xl tf:border tf:p-2", onKeyDown: (event) => {
|
|
68
70
|
if (event.key !== "Escape") {
|
|
69
71
|
return;
|
|
70
72
|
}
|
|
@@ -7,7 +7,13 @@ const VARIANT_CLASSES = {
|
|
|
7
7
|
"tf:bg-tf-primary tf:text-tf-primary-foreground tf:shadow-tf-control " +
|
|
8
8
|
"tf:hover:opacity-90 tf:disabled:opacity-50",
|
|
9
9
|
ghost: "tf:justify-center tf:rounded-tf tf:border-0 tf:px-3 tf:py-1.5 tf:text-tf-label tf:font-medium " +
|
|
10
|
-
"tf:bg-tf-transparent tf:text-tf-foreground tf:hover:bg-tf-accent
|
|
10
|
+
"tf:bg-tf-transparent tf:text-tf-foreground tf:hover:bg-tf-accent " +
|
|
11
|
+
"tf:hover:text-tf-accent-foreground tf:disabled:opacity-50",
|
|
12
|
+
secondary: "tf:relative tf:isolate tf:justify-center tf:rounded-tf tf:border-0 tf:px-3 tf:py-1.5 " +
|
|
13
|
+
"tf:text-tf-label tf:font-medium tf:bg-tf-secondary tf:text-tf-secondary-foreground " +
|
|
14
|
+
"tf:after:pointer-events-none tf:after:absolute tf:after:inset-0 tf:after:-z-10 " +
|
|
15
|
+
"tf:after:rounded-tf tf:after:bg-tf-accent tf:after:opacity-0 tf:after:transition-opacity " +
|
|
16
|
+
"tf:hover:after:opacity-100 tf:disabled:opacity-50",
|
|
11
17
|
send: "tf:size-8 tf:shrink-0 tf:justify-center tf:rounded-full tf:border-0 " +
|
|
12
18
|
"tf:bg-tf-primary tf:text-tf-primary-foreground tf:shadow-tf-control " +
|
|
13
19
|
"tf:hover:opacity-90 tf:disabled:bg-tf-muted tf:disabled:text-tf-muted-foreground " +
|
|
@@ -16,28 +22,28 @@ const VARIANT_CLASSES = {
|
|
|
16
22
|
"tf:bg-tf-primary tf:text-tf-primary-foreground tf:shadow-tf-control " +
|
|
17
23
|
"tf:hover:opacity-90 tf:aria-disabled:cursor-not-allowed tf:aria-disabled:opacity-70",
|
|
18
24
|
icon: "tf:size-7 tf:justify-center tf:rounded-tf tf:border-0 tf:bg-tf-transparent tf:text-tf-muted-foreground " +
|
|
19
|
-
"tf:hover:bg-tf-accent tf:hover:text-tf-foreground tf:disabled:opacity-50",
|
|
25
|
+
"tf:hover:bg-tf-accent tf:hover:text-tf-accent-foreground tf:disabled:opacity-50",
|
|
20
26
|
iconFloating: "tf:justify-center tf:rounded-full tf:border tf:bg-tf-background " +
|
|
21
27
|
"tf:text-tf-muted-foreground tf:shadow-tf-control " +
|
|
22
|
-
"tf:hover:bg-tf-accent tf:hover:text-tf-foreground tf:disabled:opacity-50",
|
|
28
|
+
"tf:hover:bg-tf-accent tf:hover:text-tf-accent-foreground tf:disabled:opacity-50",
|
|
23
29
|
row: "tf:h-8 tf:w-full tf:justify-start tf:rounded-tf tf:border-0 tf:px-2.5 tf:text-left tf:text-sm tf:font-medium " +
|
|
24
30
|
"tf:bg-tf-transparent tf:text-tf-muted-foreground tf:hover:bg-tf-accent " +
|
|
25
|
-
"tf:hover:text-tf-foreground tf:aria-[current=true]:bg-tf-accent " +
|
|
26
|
-
"tf:aria-[current=true]:text-tf-foreground tf:disabled:opacity-50",
|
|
31
|
+
"tf:hover:text-tf-accent-foreground tf:aria-[current=true]:bg-tf-accent " +
|
|
32
|
+
"tf:aria-[current=true]:text-tf-accent-foreground tf:disabled:opacity-50",
|
|
27
33
|
rowAction: "tf:h-9 tf:w-full tf:justify-start tf:gap-2 tf:rounded-tf tf:border-0 tf:px-2.5 tf:text-left tf:text-sm " +
|
|
28
34
|
"tf:font-medium tf:bg-tf-transparent tf:text-tf-foreground tf:hover:bg-tf-accent " +
|
|
29
|
-
"tf:disabled:opacity-50",
|
|
35
|
+
"tf:hover:text-tf-accent-foreground tf:disabled:opacity-50",
|
|
30
36
|
rowTouch: "tf:h-11 tf:w-full tf:justify-start tf:gap-2 tf:rounded-tf tf:border-0 tf:px-3 tf:text-left " +
|
|
31
37
|
"tf:text-tf-body tf:font-medium tf:bg-tf-transparent tf:text-tf-muted-foreground " +
|
|
32
|
-
"tf:hover:bg-tf-accent tf:hover:text-tf-foreground " +
|
|
33
|
-
"tf:aria-[current=true]:bg-tf-accent tf:aria-[current=true]:text-tf-foreground " +
|
|
38
|
+
"tf:hover:bg-tf-accent tf:hover:text-tf-accent-foreground " +
|
|
39
|
+
"tf:aria-[current=true]:bg-tf-accent tf:aria-[current=true]:text-tf-accent-foreground " +
|
|
34
40
|
"tf:disabled:opacity-50",
|
|
35
41
|
rowActionTouch: "tf:h-11 tf:w-full tf:justify-start tf:gap-2 tf:rounded-tf tf:border-0 tf:px-3 tf:text-left " +
|
|
36
42
|
"tf:text-tf-body tf:font-medium tf:bg-tf-transparent tf:text-tf-foreground " +
|
|
37
|
-
"tf:hover:bg-tf-accent tf:disabled:opacity-50",
|
|
43
|
+
"tf:hover:bg-tf-accent tf:hover:text-tf-accent-foreground tf:disabled:opacity-50",
|
|
38
44
|
prompt: "tf:min-h-11 tf:w-full tf:justify-start tf:gap-2.5 tf:rounded-tf tf:border-0 tf:px-4 tf:py-2 " +
|
|
39
45
|
"tf:text-left tf:text-tf-label tf:bg-tf-transparent tf:text-tf-foreground " +
|
|
40
|
-
"tf:hover:bg-tf-accent tf:disabled:opacity-50 " +
|
|
46
|
+
"tf:hover:bg-tf-accent tf:hover:text-tf-accent-foreground tf:disabled:opacity-50 " +
|
|
41
47
|
"tf:[&_[data-tf-prompt-mark]]:text-tf-muted-foreground " +
|
|
42
48
|
"tf:[&_[data-tf-prompt-go]]:opacity-0 tf:[&_[data-tf-prompt-go]]:transition-opacity " +
|
|
43
49
|
"tf:hover:[&_[data-tf-prompt-go]]:opacity-100 " +
|
|
@@ -46,21 +52,23 @@ const VARIANT_CLASSES = {
|
|
|
46
52
|
bare: "tf:rounded-tf tf:border-0 tf:bg-tf-transparent tf:p-0 tf:text-inherit tf:disabled:opacity-50",
|
|
47
53
|
chip: "tf:rounded-full tf:border-0 tf:px-2 tf:py-1 tf:text-tf-label tf:font-medium " +
|
|
48
54
|
"tf:bg-tf-transparent tf:text-tf-foreground tf:hover:bg-tf-accent " +
|
|
49
|
-
"tf:disabled:opacity-50",
|
|
55
|
+
"tf:hover:text-tf-accent-foreground tf:disabled:opacity-50",
|
|
50
56
|
chipQuiet: "tf:rounded-full tf:border-0 tf:px-2 tf:py-1 tf:text-tf-label tf:font-medium " +
|
|
51
57
|
"tf:bg-tf-transparent tf:text-tf-muted-foreground tf:hover:bg-tf-accent " +
|
|
52
|
-
"tf:hover:text-tf-foreground tf:disabled:opacity-50",
|
|
58
|
+
"tf:hover:text-tf-accent-foreground tf:disabled:opacity-50",
|
|
53
59
|
outline: "tf:justify-center tf:rounded-full tf:border tf:px-2.5 tf:py-[5px] tf:text-tf-label tf:font-medium " +
|
|
54
60
|
"tf:bg-tf-background tf:text-tf-foreground tf:shadow-tf-control " +
|
|
55
|
-
"tf:hover:bg-tf-accent tf:disabled:opacity-50",
|
|
61
|
+
"tf:hover:bg-tf-accent tf:hover:text-tf-accent-foreground tf:disabled:opacity-50",
|
|
62
|
+
glassChip: "tf:justify-center tf:rounded-full tf:border tf:px-2.5 tf:py-[5px] tf:text-tf-label " +
|
|
63
|
+
"tf:font-normal tf:disabled:opacity-50",
|
|
56
64
|
answerRow: "tf:min-h-11 tf:w-full tf:items-start tf:justify-start tf:gap-3 tf:rounded-tf tf:border-0 " +
|
|
57
65
|
"tf:bg-tf-transparent tf:px-3 tf:py-2.5 tf:text-left tf:text-tf-label tf:text-tf-foreground " +
|
|
58
|
-
"tf:wrap-anywhere tf:hover:bg-tf-accent tf:
|
|
59
|
-
"tf:aria-checked:bg-tf-emphasis",
|
|
66
|
+
"tf:wrap-anywhere tf:hover:bg-tf-accent tf:hover:text-tf-accent-foreground " +
|
|
67
|
+
"tf:disabled:opacity-50 tf:aria-checked:bg-tf-emphasis tf:aria-checked:text-tf-foreground",
|
|
60
68
|
};
|
|
61
69
|
export const TfButton = forwardRef(function TfButton({ variant = "primary", className, type, ...props }, ref) {
|
|
62
|
-
return (_jsx("button", { ref: ref, type: type ?? "button", className: cx("tf:appearance-none", "tf:inline-flex tf:items-center tf:gap-1.5 tf:transition-colors", "tf:focus-visible:outline-2 tf:focus-visible:outline-offset-2 tf:focus-visible:outline-tf-ring", "tf:disabled:cursor-not-allowed", VARIANT_CLASSES[variant], className), ...props }));
|
|
70
|
+
return (_jsx("button", { ref: ref, type: type ?? "button", ...(variant === "secondary" ? { "data-tf-secondary": "" } : {}), className: cx("tf:appearance-none", "tf:inline-flex tf:items-center tf:gap-1.5 tf:transition-colors", "tf:focus-visible:outline-2 tf:focus-visible:outline-offset-2 tf:focus-visible:outline-tf-ring", "tf:disabled:cursor-not-allowed", VARIANT_CLASSES[variant], className), ...props }));
|
|
63
71
|
});
|
|
64
72
|
export function TfLinkButton({ variant = "primary", className, children, ...props }) {
|
|
65
|
-
return (_jsx("a", { className: cx("tf:appearance-none tf:no-underline", "tf:inline-flex tf:items-center tf:gap-1.5 tf:transition-colors", "tf:focus-visible:outline-2 tf:focus-visible:outline-offset-2 tf:focus-visible:outline-tf-ring", VARIANT_CLASSES[variant], className), ...props, children: children }));
|
|
73
|
+
return (_jsx("a", { ...(variant === "secondary" ? { "data-tf-secondary": "" } : {}), className: cx("tf:appearance-none tf:no-underline", "tf:inline-flex tf:items-center tf:gap-1.5 tf:transition-colors", "tf:focus-visible:outline-2 tf:focus-visible:outline-offset-2 tf:focus-visible:outline-tf-ring", VARIANT_CLASSES[variant], className), ...props, children: children }));
|
|
66
74
|
}
|
|
@@ -42,7 +42,7 @@ export function TfFloatingPanel({ open, onOpenChange, corner = "bottom-right", d
|
|
|
42
42
|
handleSelector: "[data-tf-swipe-handle]",
|
|
43
43
|
});
|
|
44
44
|
useDockReflow(panelRef, dock);
|
|
45
|
-
return (_jsx("div", { ref: panelRef, popover: "manual", role: "dialog", "data-tf-assistant": "", "data-tf-floating-panel": corner, "data-tf-panel-dock": dock, "data-tf-glass": dock === "floating" ? "" : undefined, onToggle: parkOnForcedHide, onKeyDown: closeFromEscape, onPointerDown: swipe.onPointerDown, onPointerMove: swipe.onPointerMove, onPointerUp: swipe.onPointerUp, onPointerCancel: swipe.onPointerCancel, onClickCapture: swipe.onClickCapture, className: cx("tf:m-0 tf:hidden tf:p-0 tf:open:flex!", "tf:flex-col tf:overflow-hidden
|
|
45
|
+
return (_jsx("div", { ref: panelRef, popover: "manual", role: "dialog", "data-tf-assistant": "", "data-tf-floating-panel": corner, "data-tf-panel-dock": dock, "data-tf-glass": dock === "floating" ? "" : undefined, onToggle: parkOnForcedHide, onKeyDown: closeFromEscape, onPointerDown: swipe.onPointerDown, onPointerMove: swipe.onPointerMove, onPointerUp: swipe.onPointerUp, onPointerCancel: swipe.onPointerCancel, onClickCapture: swipe.onClickCapture, className: cx("tf:m-0 tf:hidden tf:p-0 tf:open:flex!", "tf:flex-col tf:overflow-hidden", dock === "sidebar"
|
|
46
46
|
?
|
|
47
47
|
"tf:inset-y-0 tf:right-0 tf:left-auto tf:h-dvh tf:w-104 tf:max-w-[calc(100vw-2rem)] tf:rounded-none tf:bg-tf-background tf:shadow-none"
|
|
48
48
|
: cx("tf:inset-auto tf:bottom-4 tf:w-[clamp(24rem,44vw,46rem)] tf:max-w-[calc(100vw-2rem)]", "tf:h-[min(68dvh,52rem,calc(100dvh-6rem))]", "tf:rounded-3xl tf:border", corner === "bottom-left" ? "tf:left-4" : "tf:right-4"), className), ...props, children: children }));
|
|
@@ -85,7 +85,7 @@ export function ProviderChip({ statuses, open, onOpenChange, fundingNote, }) {
|
|
|
85
85
|
event.preventDefault();
|
|
86
86
|
event.stopPropagation();
|
|
87
87
|
onOpenChange(false);
|
|
88
|
-
}, children: [_jsx(OpenAiMarkIcon, {}), _jsx("span", { className: "tf:whitespace-nowrap", children: headline.label }), _jsx(ChevronDownIcon, {})] }), open ? (_jsxs("div", { ref: menuRef, id: "tf-provider-chip-menu", role: "dialog", "aria-label": headline.accessibleName, "data-tf-glass": "", className: "tf:absolute tf:right-0 tf:bottom-full tf:mb-2 tf:flex tf:w-80 tf:max-w-[calc(100vw-2rem)] tf:flex-col tf:gap-3 tf:overflow-y-auto tf:rounded-2xl tf:border tf:p-3", onKeyDown: (event) => {
|
|
88
|
+
}, children: [_jsx(OpenAiMarkIcon, {}), _jsx("span", { className: "tf:whitespace-nowrap", children: headline.label }), _jsx(ChevronDownIcon, {})] }), open ? (_jsxs("div", { ref: menuRef, id: "tf-provider-chip-menu", role: "dialog", "aria-label": headline.accessibleName, "data-tf-glass": "", "data-tf-popover": "", className: "tf:absolute tf:right-0 tf:bottom-full tf:mb-2 tf:flex tf:w-80 tf:max-w-[calc(100vw-2rem)] tf:flex-col tf:gap-3 tf:overflow-y-auto tf:rounded-2xl tf:border tf:p-3", onKeyDown: (event) => {
|
|
89
89
|
if (event.key !== "Escape") {
|
|
90
90
|
return;
|
|
91
91
|
}
|
|
@@ -112,6 +112,13 @@ function _chipHeadlineOf(statuses) {
|
|
|
112
112
|
connected: false,
|
|
113
113
|
};
|
|
114
114
|
}
|
|
115
|
+
if (!holding.offered) {
|
|
116
|
+
return {
|
|
117
|
+
label: `${name} · not in use`,
|
|
118
|
+
accessibleName: `${name} plan — not in use`,
|
|
119
|
+
connected: true,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
115
122
|
if (holding.state === "verifying") {
|
|
116
123
|
return {
|
|
117
124
|
label: `${name} · verifying…`,
|
|
@@ -8,7 +8,7 @@ export function QuestionPanelFooter({ card, cursor, gateReason, disabled, submit
|
|
|
8
8
|
const total = card.questions.length;
|
|
9
9
|
const isLast = cursor === total - 1;
|
|
10
10
|
const { confirming, cancelRef, keepEditingRef, requestCancel, keepEditing, discard, } = useCancelConfirm(card);
|
|
11
|
-
return (_jsx("div", { "data-tf-question-footer": "", className: "tf:mt-3 tf:flex tf:flex-wrap tf:items-center tf:justify-end tf:gap-2", children: card.status === "submitting" ? (_jsx("p", { className: "tf:flex tf:items-center tf:gap-2 tf:text-tf-label tf:text-tf-muted-foreground", children: _jsx(Spinner, { label: "Sending\u2026" }) })) : confirming ? (_jsxs(Fragment, { children: [_jsx("span", { className: "tf:text-tf-label tf:text-tf-muted-foreground", children: "Discard answers?" }), _jsx(TfButton, { ref: keepEditingRef, variant: "
|
|
11
|
+
return (_jsx("div", { "data-tf-question-footer": "", className: "tf:mt-3 tf:flex tf:flex-wrap tf:items-center tf:justify-end tf:gap-2", children: card.status === "submitting" ? (_jsx("p", { className: "tf:flex tf:items-center tf:gap-2 tf:text-tf-label tf:text-tf-muted-foreground", children: _jsx(Spinner, { label: "Sending\u2026" }) })) : confirming ? (_jsxs(Fragment, { children: [_jsx("span", { className: "tf:text-tf-label tf:text-tf-muted-foreground", children: "Discard answers?" }), _jsx(TfButton, { ref: keepEditingRef, variant: "secondary", onClick: keepEditing, children: "Keep editing" }), _jsx(TfButton, { variant: "outline", onClick: discard, children: "Discard" })] }, "confirm")) : (_jsxs(Fragment, { children: [gateReason !== null ? (_jsx("span", { "data-tf-question-gate": "", className: "tf:me-auto tf:text-tf-label tf:text-tf-muted-foreground", children: gateReason })) : null, _jsx(TfButton, { ref: cancelRef, variant: "secondary", disabled: disabled, onClick: requestCancel, children: "Cancel" }), _jsx(TfButton, { variant: "primary", disabled: disabled || submitGated, onClick: onProceed, children: isLast
|
|
12
12
|
? total === 1
|
|
13
13
|
? "Submit answer"
|
|
14
14
|
: "Submit answers"
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import { type ComponentType } from "react";
|
|
2
2
|
import type { ToolViewAdapter, ToolViewProps } from "../core/tool-view.js";
|
|
3
|
+
/**
|
|
4
|
+
* Wraps a React component as a tool view (or as an icon) for a registration;
|
|
5
|
+
* the component receives ToolViewProps and keeps its state across updates. It
|
|
6
|
+
* renders in its own React root, so your app's providers (router, theme, data
|
|
7
|
+
* clients) don't reach it, and a render error makes the assistant show the next
|
|
8
|
+
* matching view.
|
|
9
|
+
*/
|
|
3
10
|
export declare function reactToolView<TArgs = Record<string, unknown>, TResult = unknown>(component: ComponentType<ToolViewProps<TArgs, TResult>>): ToolViewAdapter<TArgs, TResult>;
|
|
4
11
|
export declare const TOOL_VIEW_LATE_FAILURE_EVENT = "teaflask-tool-view-late-failure";
|
|
@@ -26,7 +26,7 @@ export function SubagentCountPill({ dispatches, threadId, renderPreview, }) {
|
|
|
26
26
|
return null;
|
|
27
27
|
}
|
|
28
28
|
const variantIndices = coworkerIndicesOf(dispatches.values());
|
|
29
|
-
return (_jsxs("div", { ref: wrapperRef, "data-tf-subagent-pill": "", "data-tf-shelf-item": "", className: "tf:pointer-events-auto tf:relative tf:w-fit", onPointerEnter: onWrapperPointerEnter, onPointerLeave: onWrapperPointerLeave, onBlur: onWrapperBlur, children: [_jsxs(TfButton, { ref: triggerRef, "data-tf-glass": "", variant: "
|
|
29
|
+
return (_jsxs("div", { ref: wrapperRef, "data-tf-subagent-pill": "", "data-tf-shelf-item": "", className: "tf:pointer-events-auto tf:relative tf:w-fit", onPointerEnter: onWrapperPointerEnter, onPointerLeave: onWrapperPointerLeave, onBlur: onWrapperBlur, children: [_jsxs(TfButton, { ref: triggerRef, "data-tf-glass": "", variant: "glassChip", className: "tf:min-h-11 tf:px-3 tf:md:px-2.5", "aria-label": `Subagents: ${label}`, "aria-expanded": open, "aria-controls": open ? rosterId : undefined, onPointerDown: onTriggerPointerDown, onPointerCancel: onTriggerPointerCancel, onFocus: onTriggerFocus, onClick: onTriggerClick, onKeyDown: onTriggerKeyDown, children: [_jsx(AgentIdentityMark, { register: "subagent", size: "md", className: "tf:text-tf-muted-foreground" }), roster.failed.length > 0 ? (_jsx("span", { "aria-hidden": true, className: "tf:size-1.5 tf:shrink-0 tf:rounded-full tf:bg-tf-destructive" })) : null, roster.running.length > 0 ? (_jsx(ShimmerText, { className: "tf:text-tf-muted-foreground", children: label })) : (label)] }), open ? (_jsx(SubagentRosterCard, { id: rosterId, roster: roster, variantIndices: variantIndices, threadId: threadId, renderPreview: renderPreview, triggerRef: triggerRef, onClose: close, refocusTrigger: refocusTrigger })) : null] }));
|
|
30
30
|
}
|
|
31
31
|
function SubagentRosterCard({ id, roster, variantIndices, threadId, renderPreview, triggerRef, onClose, refocusTrigger, }) {
|
|
32
32
|
const cardRef = useRef(null);
|
|
@@ -87,7 +87,7 @@ function SubagentRosterLine({ entry, variantIndex, previewable, previewOpen, onP
|
|
|
87
87
|
entry.failed ? entry.note : null,
|
|
88
88
|
]
|
|
89
89
|
.filter((part) => part !== null)
|
|
90
|
-
.join(" — "), className: "tf:group/subagent tf:min-h-11 tf:w-full tf:justify-start tf:px-2 tf:py-1.5 tf:hover:bg-tf-accent", onPointerEnter: (event) => {
|
|
90
|
+
.join(" — "), className: "tf:group/subagent tf:min-h-11 tf:w-full tf:justify-start tf:px-2 tf:py-1.5 tf:hover:bg-tf-accent tf:hover:text-tf-accent-foreground", onPointerEnter: (event) => {
|
|
91
91
|
if (event.pointerType !== "touch") {
|
|
92
92
|
onPreviewOpener(event.currentTarget);
|
|
93
93
|
onPreviewChange(true);
|
|
@@ -3,10 +3,9 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
import { activityTitleOf } from "../core/activity-title.js";
|
|
4
4
|
import { ChevronRightIcon } from "lucide-react";
|
|
5
5
|
import { createContext, useContext } from "react";
|
|
6
|
-
import { dispatchFailed, dispatchIsPaused, dispatchIsRunning, } from "../contract/dispatches.js";
|
|
7
|
-
import { subagentIdentityTokenOf } from "../core/agent-identity.js";
|
|
8
6
|
import { coworkerIndicesOf, settledWorkedLabelOf, } from "../core/subagent-presence.js";
|
|
9
7
|
import { subagentGroupHeadlineOf, subagentOutcomeCountsOf, } from "../core/subagent-rows.js";
|
|
8
|
+
import { resolvedSubagentEntryOf, } from "../core/subagent-ledger-join.js";
|
|
10
9
|
import { humanizedToolName, } from "../core/tool-call-display.js";
|
|
11
10
|
import { toolCallPresentationOf } from "../core/tool-call-presentation.js";
|
|
12
11
|
import { AgentIdentityMark } from "./agent-identity-mark.js";
|
|
@@ -21,30 +20,6 @@ const EMPTY_SUBAGENT_DISPATCHES = {
|
|
|
21
20
|
byOrdinal: new Map(),
|
|
22
21
|
};
|
|
23
22
|
export const SubagentDispatchesContext = createContext(EMPTY_SUBAGENT_DISPATCHES);
|
|
24
|
-
export function resolvedSubagentEntryOf(entry, byOrdinal) {
|
|
25
|
-
const ledger = entry.receipt != null ? byOrdinal.get(entry.receipt.ordinal) : undefined;
|
|
26
|
-
const ledgerLabel = ledger !== undefined && ledger.label !== "" ? ledger.label : null;
|
|
27
|
-
const childSessionId = ledger !== undefined && entry.receipt?.childSessionId != null
|
|
28
|
-
? entry.receipt.childSessionId
|
|
29
|
-
: null;
|
|
30
|
-
const running = ledger !== undefined ? dispatchIsRunning(ledger) : entry.running;
|
|
31
|
-
const failed = ledger !== undefined ? dispatchFailed(ledger) : entry.failed;
|
|
32
|
-
return {
|
|
33
|
-
toolCallId: entry.toolCallId,
|
|
34
|
-
label: ledgerLabel ?? entry.label,
|
|
35
|
-
running,
|
|
36
|
-
failed,
|
|
37
|
-
cancelled: entry.cancelled,
|
|
38
|
-
note: (ledger !== undefined && dispatchFailed(ledger) ? ledger.error : null) ??
|
|
39
|
-
entry.note,
|
|
40
|
-
childSessionId,
|
|
41
|
-
identityToken: childSessionId !== null ? subagentIdentityTokenOf(childSessionId) : null,
|
|
42
|
-
ordinal: entry.receipt?.ordinal ?? null,
|
|
43
|
-
paused: ledger !== undefined && dispatchIsPaused(ledger),
|
|
44
|
-
startedAt: ledger !== undefined ? ledger.created_at : null,
|
|
45
|
-
settledAt: ledger !== undefined && !running ? ledger.updated_at : null,
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
23
|
export function SubagentGroupRow({ row }) {
|
|
49
24
|
const join = useContext(SubagentDispatchesContext);
|
|
50
25
|
const resolved = row.entries.map((entry) => resolvedSubagentEntryOf(entry, join.byOrdinal));
|
|
@@ -43,7 +43,7 @@ export function SubagentPreviewPopover({ id, anchorRef, previewRef, label, child
|
|
|
43
43
|
}
|
|
44
44
|
};
|
|
45
45
|
}, [anchorRef, previewRef]);
|
|
46
|
-
return (_jsxs("div", { ref: previewRef, id: id, role: "dialog", "aria-label": `Conversation preview: ${label}`, popover: "manual", tabIndex: -1, className: "tf:fixed tf:m-0 tf:overflow-visible tf:border-0 tf:bg-transparent tf:p-0 tf:text-tf-foreground tf:focus-visible:outline-2 tf:focus-visible:outline-offset-2 tf:focus-visible:outline-tf-ring", children: [_jsx("span", { "aria-hidden": true, "data-tf-subagent-preview-hover-bridge": "", className: "tf:pointer-events-auto tf:absolute tf:-inset-2" }), _jsx("div", { className: "tf:relative tf:h-full tf:w-full", children: children })] }));
|
|
46
|
+
return (_jsxs("div", { ref: previewRef, id: id, role: "dialog", "aria-label": `Conversation preview: ${label}`, popover: "manual", tabIndex: -1, className: "tf:fixed tf:m-0 tf:overflow-visible tf:border-0 tf:bg-transparent tf:p-0 tf:text-tf-popover-foreground tf:focus-visible:outline-2 tf:focus-visible:outline-offset-2 tf:focus-visible:outline-tf-ring", children: [_jsx("span", { "aria-hidden": true, "data-tf-subagent-preview-hover-bridge": "", className: "tf:pointer-events-auto tf:absolute tf:-inset-2" }), _jsx("div", { className: "tf:relative tf:h-full tf:w-full", children: children })] }));
|
|
47
47
|
}
|
|
48
48
|
function _previewPlacementOf(anchorRect, viewportWidth, viewportHeight) {
|
|
49
49
|
const gutter = 16;
|
|
@@ -33,11 +33,13 @@ export function ManageUsageLink({ provider, variant = "primary", }) {
|
|
|
33
33
|
export function HeartbeatLine({ sentence, tone = "muted", }) {
|
|
34
34
|
return (_jsxs("p", { className: tone === "muted"
|
|
35
35
|
? "tf:m-0 tf:flex tf:items-center tf:gap-1.5 tf:text-tf-label tf:text-tf-muted-foreground"
|
|
36
|
-
: "tf:m-0 tf:flex tf:items-center tf:gap-1.5 tf:text-tf-label
|
|
36
|
+
: "tf:m-0 tf:flex tf:items-center tf:gap-1.5 tf:text-tf-label", role: "status", children: [_jsx("span", { "aria-hidden": true, className: tone === "muted"
|
|
37
|
+
? "tf:size-1.5 tf:shrink-0 tf:animate-tf-pulse tf:rounded-full tf:bg-tf-foreground tf:motion-reduce:animate-none"
|
|
38
|
+
: "tf:size-1.5 tf:shrink-0 tf:animate-tf-pulse tf:rounded-full tf:bg-current tf:motion-reduce:animate-none" }), sentence] }));
|
|
37
39
|
}
|
|
38
|
-
export function PopupBlocked({
|
|
39
|
-
return (_jsxs("div", { className: "tf:flex tf:flex-col tf:gap-2", children: [_jsx("p", { className: "tf:m-0 tf:text-tf-label
|
|
40
|
+
export function PopupBlocked({ onBegin, onCancel, }) {
|
|
41
|
+
return (_jsxs("div", { className: "tf:flex tf:flex-col tf:gap-2", children: [_jsx("p", { className: "tf:m-0 tf:text-tf-label", role: "status", children: "Your browser blocked the sign-in window. Allow pop-ups for this site, then try again." }), _jsxs("div", { className: "tf:flex tf:flex-wrap tf:items-center tf:gap-2", children: [_jsx(TfButton, { variant: "primary", onClick: onBegin, children: "Try again" }), _jsx(TfButton, { variant: "secondary", onClick: onCancel, children: "Cancel" })] })] }));
|
|
40
42
|
}
|
|
41
43
|
export function NotConnected({ name, onBegin, }) {
|
|
42
|
-
return (_jsxs("div", { className: "tf:flex tf:flex-col tf:gap-2", children: [_jsxs("div", { className: "tf:flex tf:flex-col tf:gap-1", role: "status", children: [_jsx("p", { className: "tf:m-0 tf:text-tf-heading tf:font-medium
|
|
44
|
+
return (_jsxs("div", { className: "tf:flex tf:flex-col tf:gap-2", children: [_jsxs("div", { className: "tf:flex tf:flex-col tf:gap-1", role: "status", children: [_jsx("p", { className: "tf:m-0 tf:text-tf-heading tf:font-medium", children: NOT_CONNECTED_HEADLINE }), _jsx("p", { className: "tf:m-0 tf:text-tf-label tf:text-tf-muted-foreground", children: notConnectedExplanationOf(name) })] }), _jsx(TfButton, { variant: "primary", className: "tf:self-start", onClick: onBegin, children: "Try again" })] }));
|
|
43
45
|
}
|