@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
|
@@ -1,29 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which palette the assistant uses. `"light"` and `"dark"` force that palette,
|
|
3
|
+
* and `"auto"` follows the visitor's operating-system setting.
|
|
4
|
+
*/
|
|
1
5
|
export type AssistantThemeMode = "light" | "dark" | "auto";
|
|
6
|
+
/**
|
|
7
|
+
* The themable tokens. Each one sets a `--tf-` CSS variable, and you can set
|
|
8
|
+
* those variables in your own CSS on any ancestor instead of passing them here.
|
|
9
|
+
* Values are CSS strings (any CSS color for the color tokens), and a token you
|
|
10
|
+
* omit keeps the default monochrome look.
|
|
11
|
+
*/
|
|
2
12
|
export interface AssistantThemeTokens {
|
|
13
|
+
/**
|
|
14
|
+
* Sets `--tf-background`, the base surface color behind the conversation,
|
|
15
|
+
* the composer and floating controls. Defaults to `#ffffff` in light mode
|
|
16
|
+
* and `#000000` in dark mode.
|
|
17
|
+
*/
|
|
3
18
|
background?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Sets `--tf-foreground`, the main text and icon color. Defaults to
|
|
21
|
+
* `#171717` in light mode and `#ededed` in dark mode.
|
|
22
|
+
*/
|
|
4
23
|
foreground?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Sets `--tf-card`, the fill of approval cards and tool views in the
|
|
26
|
+
* conversation. Defaults to `#ffffff` in light mode and `#000000` in dark
|
|
27
|
+
* mode; it does not follow `background`, so set both to change cards too.
|
|
28
|
+
*/
|
|
5
29
|
card?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Sets `--tf-card-foreground`, the text color inside approval cards and
|
|
32
|
+
* tool views: an approval's heading, and the row titles, badges and values
|
|
33
|
+
* of a tool view, including the request details an approval can show. An
|
|
34
|
+
* approval's request sentence and the other lines inside these cards use
|
|
35
|
+
* `mutedForeground`. Defaults to the same value as `foreground`.
|
|
36
|
+
*/
|
|
6
37
|
cardForeground?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Sets `--tf-popover`, the fill of the floating menus: the conversation
|
|
40
|
+
* history menu, the panel-position menu, the model picker, the ChatGPT plan
|
|
41
|
+
* menu, the command palette and the sub-agent preview. These surfaces are
|
|
42
|
+
* translucent, so the color is applied as a tint over what sits behind
|
|
43
|
+
* them; give it the same light or dark polarity as `background`. The
|
|
44
|
+
* floating panel, the mobile sheet and the sub-agent chip keep
|
|
45
|
+
* `background`. Defaults to the same value as `background`.
|
|
46
|
+
*/
|
|
7
47
|
popover?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Sets `--tf-popover-foreground`, the text color the `popover` surfaces
|
|
50
|
+
* inherit: a menu's heading, the ChatGPT plan menu's connected standing,
|
|
51
|
+
* the command palette's heading and the sub-agent preview's text. Menu rows
|
|
52
|
+
* use `mutedForeground` at rest and `accentForeground` when hovered, the
|
|
53
|
+
* New conversation row at the top of the history menu keeps `foreground`,
|
|
54
|
+
* and the conversation shown inside the command palette keeps its own
|
|
55
|
+
* colors. Defaults to the same value as `foreground`.
|
|
56
|
+
*/
|
|
8
57
|
popoverForeground?: string;
|
|
58
|
+
/**
|
|
59
|
+
* Sets `--tf-primary`, the fill of solid buttons such as Send and Stop.
|
|
60
|
+
* Defaults to `#171717` in light mode and `#ededed` in dark mode.
|
|
61
|
+
*/
|
|
9
62
|
primary?: string;
|
|
63
|
+
/**
|
|
64
|
+
* Sets `--tf-primary-foreground`, the text and icon color on `primary`
|
|
65
|
+
* buttons.
|
|
66
|
+
*/
|
|
10
67
|
primaryForeground?: string;
|
|
68
|
+
/**
|
|
69
|
+
* Sets `--tf-secondary`, the fill of the secondary buttons: Deny, Back and
|
|
70
|
+
* the Approve-for-this-task or Approve-for-this-conversation option on an
|
|
71
|
+
* approval card, Cancel and Keep editing under a question, and Cancel while
|
|
72
|
+
* a ChatGPT sign-in is in progress. Hovered, the fill shifts slightly
|
|
73
|
+
* toward its own text color under a light `accent` wash, so a themed fill
|
|
74
|
+
* stays visible. Defaults to transparent, so these buttons stay quiet until
|
|
75
|
+
* you set it.
|
|
76
|
+
*/
|
|
11
77
|
secondary?: string;
|
|
78
|
+
/**
|
|
79
|
+
* Sets `--tf-secondary-foreground`, the text color on `secondary` buttons,
|
|
80
|
+
* at rest and hovered. Defaults to the same value as `foreground`.
|
|
81
|
+
*/
|
|
12
82
|
secondaryForeground?: string;
|
|
83
|
+
/**
|
|
84
|
+
* Sets `--tf-muted`, the subtle fill behind the user's own messages, code
|
|
85
|
+
* blocks and the disabled Send button. Defaults to `#f2f2f2` in light mode
|
|
86
|
+
* and `#1a1a1a` in dark mode.
|
|
87
|
+
*/
|
|
13
88
|
muted?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Sets `--tf-muted-foreground`, the color of secondary text, captions and
|
|
91
|
+
* quiet icons.
|
|
92
|
+
*/
|
|
14
93
|
mutedForeground?: string;
|
|
94
|
+
/**
|
|
95
|
+
* Sets `--tf-accent`, the hover fill of quiet buttons, menu rows and list
|
|
96
|
+
* rows. Defaults to a 5% black tint in light mode and a 7% white tint in
|
|
97
|
+
* dark mode.
|
|
98
|
+
*/
|
|
15
99
|
accent?: string;
|
|
100
|
+
/**
|
|
101
|
+
* Sets `--tf-accent-foreground`, the text color over the `accent` fill:
|
|
102
|
+
* hovered menu rows, list rows, answer rows and quiet buttons, the selected
|
|
103
|
+
* conversation in the history menu, and the title and badge of a hovered
|
|
104
|
+
* link row in a tool view. Defaults to the same value as `foreground`.
|
|
105
|
+
*/
|
|
16
106
|
accentForeground?: string;
|
|
107
|
+
/**
|
|
108
|
+
* Sets `--tf-destructive`, the color of error text, failure icons and
|
|
109
|
+
* destructive controls.
|
|
110
|
+
*/
|
|
17
111
|
destructive?: string;
|
|
112
|
+
/**
|
|
113
|
+
* Sets `--tf-border`, the color of every border and divider inside the
|
|
114
|
+
* assistant.
|
|
115
|
+
*/
|
|
18
116
|
border?: string;
|
|
117
|
+
/**
|
|
118
|
+
* Sets `--tf-input`, the border color of the message box and of keyboard
|
|
119
|
+
* shortcut hints.
|
|
120
|
+
*/
|
|
19
121
|
input?: string;
|
|
122
|
+
/**
|
|
123
|
+
* Sets `--tf-ring`, the focus outline shown when a control is focused from
|
|
124
|
+
* the keyboard. Defaults to `#0070f7` in light mode and `#50a8ff` in dark
|
|
125
|
+
* mode.
|
|
126
|
+
*/
|
|
20
127
|
ring?: string;
|
|
128
|
+
/**
|
|
129
|
+
* Sets `--tf-radius`, the corner radius for buttons, inputs and panels,
|
|
130
|
+
* with some elements derived from it. A bare number means pixels, and the
|
|
131
|
+
* default is `0.5rem`.
|
|
132
|
+
*/
|
|
21
133
|
radius?: string | number;
|
|
134
|
+
/**
|
|
135
|
+
* Sets `--tf-font-sans`, the font-family stack for all assistant text.
|
|
136
|
+
* Defaults to the system UI font.
|
|
137
|
+
*/
|
|
22
138
|
fontSans?: string;
|
|
139
|
+
/**
|
|
140
|
+
* Sets `--tf-color-scheme`, the CSS `color-scheme` that native controls
|
|
141
|
+
* such as scrollbars and the message box draw with (`"light"` or `"dark"`).
|
|
142
|
+
* By default it follows the active mode. Set it when you build a dark theme
|
|
143
|
+
* from tokens alone, and note that a value you set applies in both modes.
|
|
144
|
+
*/
|
|
23
145
|
colorScheme?: string;
|
|
24
146
|
}
|
|
147
|
+
/**
|
|
148
|
+
* The tokens you can override for dark mode: every color token, but not
|
|
149
|
+
* `radius`, `fontSans` or `colorScheme`, which stay the same in both modes.
|
|
150
|
+
*/
|
|
25
151
|
export type AssistantThemeDarkTokens = Omit<AssistantThemeTokens, "radius" | "fontSans" | "colorScheme">;
|
|
152
|
+
/**
|
|
153
|
+
* Colors, corner radius and font for every assistant surface, passed as the
|
|
154
|
+
* `theme` prop; each token sets one `--tf-` CSS variable inline on the
|
|
155
|
+
* assistant's root elements, so it overrides the same variable set in your own
|
|
156
|
+
* CSS.
|
|
157
|
+
*/
|
|
26
158
|
export interface AssistantTheme extends AssistantThemeTokens {
|
|
159
|
+
/**
|
|
160
|
+
* Color overrides used only while dark mode is active (`mode="dark"`,
|
|
161
|
+
* `mode="auto"` on a dark OS, or `data-tf-theme="dark"` on an ancestor). A
|
|
162
|
+
* color you leave out here falls back to the base token if you set one,
|
|
163
|
+
* otherwise to the built-in dark default.
|
|
164
|
+
*/
|
|
27
165
|
dark?: AssistantThemeDarkTokens;
|
|
28
166
|
}
|
|
29
167
|
export declare const THEME_TOKEN_KEYS: readonly (keyof AssistantThemeTokens)[];
|
|
@@ -49,7 +49,7 @@ export function ApprovalCard({ card }) {
|
|
|
49
49
|
setSubmittedForStatus(card.status);
|
|
50
50
|
void submitDecision(card, decision);
|
|
51
51
|
};
|
|
52
|
-
return (_jsxs("div", { "data-tf-approval-card": "", className: "tf:my-2 tf:rounded-2xl tf:border tf:border-tf-border tf:bg-tf-card tf:p-4", role: "group", "aria-label": "Approval request", children: [_jsx(CardHeader, { card: card }), _jsx("p", { "data-tf-approval-prompt": "", className: "tf:mt-3 tf:m-0 tf:text-tf-label tf:leading-relaxed tf:text-tf-muted-foreground", children: card.prompt.trim() === ""
|
|
52
|
+
return (_jsxs("div", { "data-tf-approval-card": "", className: "tf:my-2 tf:rounded-2xl tf:border tf:border-tf-border tf:bg-tf-card tf:p-4 tf:text-tf-card-foreground", role: "group", "aria-label": "Approval request", children: [_jsx(CardHeader, { card: card }), _jsx("p", { "data-tf-approval-prompt": "", className: "tf:mt-3 tf:m-0 tf:text-tf-label tf:leading-relaxed tf:text-tf-muted-foreground", children: card.prompt.trim() === ""
|
|
53
53
|
? "This tool needs your approval before it can run."
|
|
54
54
|
: card.prompt }), _jsx("div", { "data-tf-approval-footer": "", children: _jsx(CardFooter, { card: card, denying: denying, submitted: submitted, feedback: feedback, onFeedbackChange: setFeedback, onApprove: () => {
|
|
55
55
|
submitOnce({ approved: true });
|
|
@@ -86,10 +86,10 @@ function DenialForm({ asker, feedback, submitted, onFeedbackChange, onSend, onBa
|
|
|
86
86
|
? "Tell the coworker why (optional)"
|
|
87
87
|
: "Tell the assistant why (optional)", "aria-label": "Reason for denying", onChange: (event) => {
|
|
88
88
|
onFeedbackChange(event.target.value);
|
|
89
|
-
} }), _jsxs("div", { className: "tf:flex tf:gap-2", children: [_jsx(TfButton, { disabled: submitted, onClick: onSend, children: "Send denial" }), _jsx(TfButton, { variant: "
|
|
89
|
+
} }), _jsxs("div", { className: "tf:flex tf:gap-2", children: [_jsx(TfButton, { disabled: submitted, onClick: onSend, children: "Send denial" }), _jsx(TfButton, { variant: "secondary", disabled: submitted, onClick: onBack, children: "Back" })] })] }));
|
|
90
90
|
}
|
|
91
91
|
function DecisionButtons({ card, submitted, onApprove, onApproveAndTrust, onStartDenying, }) {
|
|
92
|
-
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "tf:flex tf:flex-wrap tf:gap-2", children: [_jsx(TfButton, { disabled: submitted, onClick: onApprove, children: "Approve" }), _cardOffersTrust(card) ? (_jsx(TfButton, { variant: "
|
|
92
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "tf:flex tf:flex-wrap tf:gap-2", children: [_jsx(TfButton, { disabled: submitted, onClick: onApprove, children: "Approve" }), _cardOffersTrust(card) ? (_jsx(TfButton, { variant: "secondary", disabled: submitted, onClick: onApproveAndTrust, children: _trustLabelOf(card.asker) })) : null, _jsx(TfButton, { variant: "secondary", disabled: submitted, onClick: onStartDenying, children: "Deny" })] }), card.gated ? (_jsx("p", { className: "tf:m-0 tf:text-xs tf:text-tf-muted-foreground", children: GATED_NOTE })) : null] }));
|
|
93
93
|
}
|
|
94
94
|
function _cardOffersTrust(card) {
|
|
95
95
|
return !card.gated && card.trustAvailable;
|
|
@@ -1,8 +1,28 @@
|
|
|
1
1
|
import type { ApprovalCardModel, ApprovalDecisionInput } from "../core/approval-inbox.js";
|
|
2
|
+
/**
|
|
3
|
+
* The approval requests to show and the function that answers them, as returned
|
|
4
|
+
* by useApprovals().
|
|
5
|
+
*/
|
|
2
6
|
export interface ApprovalSurface {
|
|
7
|
+
/**
|
|
8
|
+
* Approval requests in the open conversation, from the assistant and its
|
|
9
|
+
* sub-agents. Requests already answered or no longer answerable can stay in
|
|
10
|
+
* the list for a while, so render by each card's status.
|
|
11
|
+
*/
|
|
3
12
|
cards: readonly ApprovalCardModel[];
|
|
13
|
+
/**
|
|
14
|
+
* Sends the visitor's decision on one request; the card shows submitting,
|
|
15
|
+
* then answered. It does not reject on a server error: the card returns to
|
|
16
|
+
* actionable with an error sentence instead, and repeat submits while one
|
|
17
|
+
* is in flight are ignored.
|
|
18
|
+
*/
|
|
4
19
|
submitDecision: (card: ApprovalCardModel, decision: ApprovalDecisionInput) => Promise<void>;
|
|
5
20
|
}
|
|
6
21
|
export declare const ApprovalsContext: import("react").Context<ApprovalSurface>;
|
|
22
|
+
/**
|
|
23
|
+
* Returns the approval requests in the open conversation and the function that
|
|
24
|
+
* answers them. Live inside <TeaflaskAssistantProvider>; outside it the list is
|
|
25
|
+
* empty and submitting rejects with an error.
|
|
26
|
+
*/
|
|
7
27
|
export declare function useApprovals(): ApprovalSurface;
|
|
8
28
|
export declare function anchoredCardsFor(cards: readonly ApprovalCardModel[], toolCallId: string): ApprovalCardModel[];
|
|
@@ -1,5 +1,20 @@
|
|
|
1
|
+
/** Props for `AssistantCompanion`. */
|
|
1
2
|
export interface AssistantCompanionProps {
|
|
3
|
+
/**
|
|
4
|
+
* The screen corner where the widget and its drawer sit. The default is
|
|
5
|
+
* `"bottom-right"`.
|
|
6
|
+
*/
|
|
2
7
|
corner?: "bottom-right" | "bottom-left";
|
|
8
|
+
/**
|
|
9
|
+
* The accessible name of the button that opens the drawer, which defaults
|
|
10
|
+
* to `"Open assistant"`.
|
|
11
|
+
*/
|
|
3
12
|
"aria-label"?: string;
|
|
4
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* The corner widget: your mark in a corner of the screen, which opens the chat
|
|
16
|
+
* drawer when clicked. On wide screens the user can switch the drawer between a
|
|
17
|
+
* floating card and a docked sidebar. It hides while a full-page assistant or
|
|
18
|
+
* the palette is open, and `TeaflaskAssistant` already includes one.
|
|
19
|
+
*/
|
|
5
20
|
export declare function AssistantCompanion(props: AssistantCompanionProps): import("react").JSX.Element;
|
|
@@ -1,23 +1,84 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
2
|
import { type AssistantSuggestionInput } from "./conversation-view.js";
|
|
3
|
+
/**
|
|
4
|
+
* The state and controls `renderChrome` receives, for drawing the full-page
|
|
5
|
+
* assistant's header controls in your own UI. The history menu itself is still
|
|
6
|
+
* rendered by the assistant.
|
|
7
|
+
*/
|
|
3
8
|
export interface AssistantChrome {
|
|
9
|
+
/** The surface title from the `title` prop, `"Assistant"` by default. */
|
|
4
10
|
title: string;
|
|
11
|
+
/**
|
|
12
|
+
* The open conversation's title, or the surface title when the conversation
|
|
13
|
+
* has none yet.
|
|
14
|
+
*/
|
|
5
15
|
conversationTitle: string;
|
|
16
|
+
/**
|
|
17
|
+
* True when the user has a conversation history to open, meaning a
|
|
18
|
+
* signed-in user. False for anonymous visitors, so hide your history
|
|
19
|
+
* button.
|
|
20
|
+
*/
|
|
6
21
|
historyAvailable: boolean;
|
|
22
|
+
/** Whether the history menu is currently open. */
|
|
7
23
|
historyOpen: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* The element id of the history menu, for `aria-controls` on your history
|
|
26
|
+
* button.
|
|
27
|
+
*/
|
|
8
28
|
historyMenuId: string;
|
|
29
|
+
/**
|
|
30
|
+
* Put this id on your history button. Clicking it then doesn't count as
|
|
31
|
+
* clicking outside the menu, and Escape returns focus to it.
|
|
32
|
+
*/
|
|
9
33
|
historyTriggerId: string;
|
|
34
|
+
/** Opens the history menu. */
|
|
10
35
|
openHistory: () => void;
|
|
36
|
+
/** Opens the history menu if it is closed and closes it if it is open. */
|
|
11
37
|
toggleHistory: () => void;
|
|
38
|
+
/** Closes the history menu and starts a new, empty conversation. */
|
|
12
39
|
newConversation: () => void;
|
|
13
40
|
}
|
|
41
|
+
/** Props for `AssistantPage`. */
|
|
14
42
|
export interface AssistantPageProps {
|
|
43
|
+
/**
|
|
44
|
+
* Removes the page's own border and rounded corners so it sits flush inside
|
|
45
|
+
* a frame you already draw. The default is false, which keeps the page as a
|
|
46
|
+
* self-contained card.
|
|
47
|
+
*/
|
|
15
48
|
frameless?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Opening prompts shown under the message box before the first message;
|
|
51
|
+
* clicking one sends it as the user's message. The full-page assistant
|
|
52
|
+
* shows none unless you pass them.
|
|
53
|
+
*/
|
|
16
54
|
suggestions?: readonly AssistantSuggestionInput[];
|
|
55
|
+
/**
|
|
56
|
+
* A message sent for the user as soon as the page opens on an empty
|
|
57
|
+
* conversation, for deep links or first-run flows. It is sent at most once
|
|
58
|
+
* per mount, never into an existing conversation and never while sign-in is
|
|
59
|
+
* required. Changing it later has no effect.
|
|
60
|
+
*/
|
|
17
61
|
initialPrompt?: string;
|
|
62
|
+
/**
|
|
63
|
+
* The heading above the empty message box, which defaults to `"Where should
|
|
64
|
+
* we begin?"`.
|
|
65
|
+
*/
|
|
18
66
|
welcomeTitle?: string;
|
|
67
|
+
/** Your own logo or artwork, shown beside the empty-state heading. */
|
|
19
68
|
welcomeMark?: ReactNode;
|
|
69
|
+
/** The name shown in the page's header, which defaults to `"Assistant"`. */
|
|
20
70
|
title?: string;
|
|
71
|
+
/**
|
|
72
|
+
* Replaces the page's built-in header with your own controls, built from
|
|
73
|
+
* the `AssistantChrome` it receives. Return a portal to put them in a bar
|
|
74
|
+
* you already have, in which case nothing renders in the header's place.
|
|
75
|
+
*/
|
|
21
76
|
renderChrome?: (chrome: AssistantChrome) => ReactNode;
|
|
22
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* The full-page assistant: the conversation with a header, a history menu and a
|
|
80
|
+
* new-conversation button, filling the box you give it. Render it inside the
|
|
81
|
+
* provider or `TeaflaskAssistant`. It shares the same conversation as the other
|
|
82
|
+
* surfaces, and the corner widget hides while it is mounted.
|
|
83
|
+
*/
|
|
23
84
|
export declare function AssistantPage(props: AssistantPageProps): import("react").JSX.Element;
|
|
@@ -1,5 +1,17 @@
|
|
|
1
|
+
/** Props for `AssistantPalette`, which is controlled by its parent. */
|
|
1
2
|
export interface AssistantPaletteProps {
|
|
3
|
+
/** Whether the palette is shown. */
|
|
2
4
|
open: boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Called with the new open state when the palette asks to open or close,
|
|
7
|
+
* for example on Escape or a backdrop click.
|
|
8
|
+
*/
|
|
3
9
|
onOpenChange: (open: boolean) => void;
|
|
4
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* The ⌘K palette: a centered dialog over your page showing the current
|
|
13
|
+
* conversation, with a way to start a new one. You control whether it is open,
|
|
14
|
+
* and Escape or a backdrop click closes it. `TeaflaskAssistant` already
|
|
15
|
+
* includes one, so render this yourself only alongside the provider.
|
|
16
|
+
*/
|
|
5
17
|
export declare function AssistantPalette(props: AssistantPaletteProps): import("react").JSX.Element;
|
|
@@ -13,8 +13,8 @@ export function AssistantPalette(props) {
|
|
|
13
13
|
function AssistantPaletteInner({ open, onOpenChange }) {
|
|
14
14
|
const { rootProps } = useAssistantAppearance();
|
|
15
15
|
useRegisterAssistantSurface("transient", open);
|
|
16
|
-
return (_jsx(TfDialog, { open: open, onOpenChange: onOpenChange, "aria-label": "Assistant", "data-tf-assistant": "", "data-tf-glass": "", "data-tf-assistant-palette": "", ...rootProps, className: "tf:m-auto tf:h-[calc(100dvh-2rem)] tf:w-[calc(100vw-2rem)] tf:flex-col " +
|
|
16
|
+
return (_jsx(TfDialog, { open: open, onOpenChange: onOpenChange, "aria-label": "Assistant", "data-tf-assistant": "", "data-tf-glass": "", "data-tf-popover": "", "data-tf-assistant-palette": "", ...rootProps, className: "tf:m-auto tf:h-[calc(100dvh-2rem)] tf:w-[calc(100vw-2rem)] tf:flex-col " +
|
|
17
17
|
"tf:overflow-hidden tf:rounded-tf tf:border " +
|
|
18
|
-
"tf:
|
|
18
|
+
"tf:backdrop:bg-black/20 " +
|
|
19
19
|
"tf:sm:mt-24 tf:sm:h-[calc(100dvh-12rem)] tf:sm:max-h-144 tf:sm:w-full tf:sm:max-w-2xl", children: open ? (_jsx(LazyBody, { children: _jsx(AssistantPaletteBody, { onOpenChange: onOpenChange }) })) : null }));
|
|
20
20
|
}
|
|
@@ -26,7 +26,7 @@ export function ChildTranscriptPreview({ threadId, childSessionId, variantIndex,
|
|
|
26
26
|
return (_jsx(ChildTranscript, { mode: "preview", threadId: threadId, childSessionId: childSessionId, variantIndex: variantIndex, opener: null, onBack: () => undefined }));
|
|
27
27
|
}
|
|
28
28
|
export function ChildTranscriptPreviewFrame({ label, status, duration, variantIndex, children, }) {
|
|
29
|
-
return (_jsxs("div", { role: "region", "aria-label": `Conversation preview: ${label}`, "data-tf-glass": "", "data-tf-child-transcript-preview": "", className: "tf:flex tf:h-full tf:w-full tf:min-h-0 tf:min-w-0 tf:flex-col tf:overflow-hidden tf:rounded-2xl tf:border
|
|
29
|
+
return (_jsxs("div", { role: "region", "aria-label": `Conversation preview: ${label}`, "data-tf-glass": "", "data-tf-popover": "", "data-tf-child-transcript-preview": "", className: "tf:flex tf:h-full tf:w-full tf:min-h-0 tf:min-w-0 tf:flex-col tf:overflow-hidden tf:rounded-2xl tf:border", children: [_jsxs("div", { className: "tf:flex tf:items-center tf:gap-2 tf:border-b tf:px-3 tf:py-2.5", children: [_jsx("span", { className: "tf:flex tf:h-6 tf:min-w-6 tf:shrink-0 tf:items-center tf:justify-center tf:px-1", children: _jsx(AgentIdentityMark, { register: "subagent", variantIndex: variantIndex }) }), _jsx(ChildStatusMark, { status: status }), status === "running" ? (_jsx(ShimmerText, { className: "tf:min-w-0 tf:flex-1 tf:grid-cols-1 tf:text-tf-label tf:font-medium tf:text-tf-muted-foreground", children: _jsx("span", { className: "tf:block tf:truncate", title: label, children: activityTitleOf(label) }) })) : (_jsx("span", { className: "tf:min-w-0 tf:flex-1 tf:truncate tf:text-tf-label tf:font-medium", title: label, children: activityTitleOf(label) })), status === "running" ? (_jsx(ShimmerText, { className: "tf:shrink-0 tf:text-xs tf:text-tf-muted-foreground", children: "Working" })) : null, duration != null ? (_jsx("span", { className: "tf:shrink-0 tf:text-xs tf:text-tf-muted-foreground", children: duration })) : null] }), children] }));
|
|
30
30
|
}
|
|
31
31
|
function ChildStatusMark({ status }) {
|
|
32
32
|
if (status === "running") {
|
|
@@ -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
|
}
|