@adecore/agents-react 0.31.12 → 0.33.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/dist/agents/AccountDot.js +57 -6
- package/dist/agents/AgentIcon.js +88 -12
- package/dist/agents/ModelOptionControl.js +153 -18
- package/dist/agents/ProviderLogo.js +49 -4
- package/dist/agents/account-limits.js +17 -14
- package/dist/agents/accounts.js +99 -67
- package/dist/agents/agent-marks.js +5 -3
- package/dist/agents/model-name.js +42 -31
- package/dist/agents/model-options.js +8 -8
- package/dist/agents/model-requirement.js +17 -14
- package/dist/agents/option-words.d.ts +7 -0
- package/dist/agents/option-words.js +35 -0
- package/dist/agents/provider-paths.js +6 -6
- package/dist/agents/status-look.js +32 -12
- package/dist/chat/account-choice.d.ts +13 -0
- package/dist/chat/account-choice.js +90 -20
- package/dist/chat/actions.js +126 -59
- package/dist/chat/activity.js +5 -5
- package/dist/chat/attachments.js +74 -53
- package/dist/chat/bookmarks.js +58 -48
- package/dist/chat/chat-client.js +344 -263
- package/dist/chat/chat-references.js +3 -3
- package/dist/chat/composer-effort.d.ts +5 -0
- package/dist/chat/composer-effort.js +26 -0
- package/dist/chat/composer-send.js +13 -13
- package/dist/chat/drafts.js +115 -79
- package/dist/chat/forks.js +81 -24
- package/dist/chat/guards.js +15 -43
- package/dist/chat/index.d.ts +3 -1
- package/dist/chat/index.js +3 -2
- package/dist/chat/logic/ansi.js +170 -167
- package/dist/chat/logic/answers.js +2 -2
- package/dist/chat/logic/bookmarks.js +19 -19
- package/dist/chat/logic/command-looks.js +138 -96
- package/dist/chat/logic/context-usage.js +13 -9
- package/dist/chat/logic/continue-after-stop.js +15 -19
- package/dist/chat/logic/effort.d.ts +14 -0
- package/dist/chat/logic/effort.js +34 -0
- package/dist/chat/logic/embedded-code.js +387 -326
- package/dist/chat/logic/fork.js +134 -110
- package/dist/chat/logic/generated-image.js +54 -23
- package/dist/chat/logic/goal.js +28 -20
- package/dist/chat/logic/handback.js +6 -6
- package/dist/chat/logic/json.js +2 -2
- package/dist/chat/logic/limit.js +46 -30
- package/dist/chat/logic/picker-entries.d.ts +5 -3
- package/dist/chat/logic/picker-entries.js +83 -43
- package/dist/chat/logic/resume-compaction.d.ts +14 -1
- package/dist/chat/logic/resume-compaction.js +93 -24
- package/dist/chat/logic/scrubber.js +188 -136
- package/dist/chat/logic/thought.js +13 -16
- package/dist/chat/logic/thread-cards.js +60 -48
- package/dist/chat/logic/timeline-copy.js +30 -38
- package/dist/chat/logic/timeline-target.js +92 -63
- package/dist/chat/logic/timeline.js +499 -355
- package/dist/chat/logic/tool-catalog.js +54 -34
- package/dist/chat/logic/tools.js +106 -82
- package/dist/chat/logic/visual-height.js +18 -18
- package/dist/chat/logic/visual-viewport.js +6 -3
- package/dist/chat/logic/welcome.js +9 -9
- package/dist/chat/logic/workflow.d.ts +10 -0
- package/dist/chat/logic/workflow.js +130 -32
- package/dist/chat/mentions.js +149 -109
- package/dist/chat/persisted-json.js +51 -54
- package/dist/chat/preferences.d.ts +4 -0
- package/dist/chat/preferences.js +162 -84
- package/dist/chat/prompt-hold.js +9 -9
- package/dist/chat/quote.js +21 -30
- package/dist/chat/reading-width.js +12 -10
- package/dist/chat/recent-messages.js +34 -21
- package/dist/chat/resume-compaction-dismissals.js +25 -5
- package/dist/chat/runtime-modes.js +3 -3
- package/dist/chat/send-key.js +11 -7
- package/dist/chat/stash.js +89 -69
- package/dist/chat/subagent-conversation.js +181 -139
- package/dist/chat/subagent-list.js +65 -67
- package/dist/chat/subagent-support.js +12 -7
- package/dist/chat/subagent-view.js +132 -44
- package/dist/chat/thumbnails.js +88 -60
- package/dist/chat/timeline-flash.js +24 -12
- package/dist/chat/timeline-scroll.js +116 -86
- package/dist/chat/ui/AccountPill.js +126 -15
- package/dist/chat/ui/AnsiOutput.js +62 -6
- package/dist/chat/ui/BookmarkMarker.js +231 -41
- package/dist/chat/ui/BookmarkSubmenu.js +165 -18
- package/dist/chat/ui/ChatActivity.js +649 -70
- package/dist/chat/ui/ChatReferenceChip.js +104 -9
- package/dist/chat/ui/CodeBlock.js +132 -58
- package/dist/chat/ui/Composer.js +866 -132
- package/dist/chat/ui/ComposerInput.js +309 -120
- package/dist/chat/ui/DiffPool.js +75 -14
- package/dist/chat/ui/EditDiff.js +160 -21
- package/dist/chat/ui/FadingWords.js +32 -3
- package/dist/chat/ui/GoalDock.js +235 -42
- package/dist/chat/ui/ImageView.js +617 -61
- package/dist/chat/ui/LimitState.js +446 -72
- package/dist/chat/ui/Markdown.js +991 -173
- package/dist/chat/ui/MermaidBlock.js +285 -79
- package/dist/chat/ui/MessageActions.js +251 -39
- package/dist/chat/ui/ModelMarks.js +55 -5
- package/dist/chat/ui/Pickers.js +664 -113
- package/dist/chat/ui/PromptComposer.js +281 -51
- package/dist/chat/ui/QuoteButton.js +151 -57
- package/dist/chat/ui/ResumeCompactionDock.d.ts +6 -2
- package/dist/chat/ui/ResumeCompactionDock.js +141 -6
- package/dist/chat/ui/RowTime.js +59 -5
- package/dist/chat/ui/RunSettings.js +1744 -154
- package/dist/chat/ui/Scrubber.js +517 -88
- package/dist/chat/ui/ShellCommand.js +183 -107
- package/dist/chat/ui/SubagentControls.js +212 -24
- package/dist/chat/ui/SubagentInfo.js +170 -13
- package/dist/chat/ui/SubagentStopButton.js +115 -24
- package/dist/chat/ui/SubagentTimeline.js +357 -91
- package/dist/chat/ui/Timeline.js +988 -476
- package/dist/chat/ui/TimelineMenu.js +552 -37
- package/dist/chat/ui/UnifiedDiff.js +234 -27
- package/dist/chat/ui/UploadThumb.js +37 -7
- package/dist/chat/ui/VisualDialogs.js +251 -20
- package/dist/chat/ui/VisualFrame.js +321 -95
- package/dist/chat/ui/Welcome.js +72 -7
- package/dist/chat/ui/chips.js +1 -1
- package/dist/chat/ui/code-lines.js +36 -36
- package/dist/chat/ui/code-streaming.js +1 -1
- package/dist/chat/ui/code-theme.js +7 -7
- package/dist/chat/ui/composer/ComposerControls.js +329 -21
- package/dist/chat/ui/composer/ComposerMenu.js +358 -30
- package/dist/chat/ui/composer/DraftParts.js +185 -11
- package/dist/chat/ui/composer/QueuedMessages.js +138 -13
- package/dist/chat/ui/composer/chips.js +29 -19
- package/dist/chat/ui/composer/editor.js +79 -63
- package/dist/chat/ui/composer/insert.js +26 -12
- package/dist/chat/ui/composer/key-handler.js +180 -127
- package/dist/chat/ui/composer/keys.js +90 -73
- package/dist/chat/ui/composer/menu-aria.js +18 -9
- package/dist/chat/ui/composer/placeholder.js +78 -31
- package/dist/chat/ui/composer/surface.js +13 -37
- package/dist/chat/ui/composer/use-chat-controls.js +230 -90
- package/dist/chat/ui/composer/use-compaction-offer.js +50 -18
- package/dist/chat/ui/composer/use-composer-draft.js +65 -34
- package/dist/chat/ui/composer/use-composer-menus.js +478 -193
- package/dist/chat/ui/composer/use-composer-submit.js +251 -109
- package/dist/chat/ui/composer/use-continuable-turn.js +33 -6
- package/dist/chat/ui/composer/use-draft-files.js +245 -93
- package/dist/chat/ui/composer/use-effort-stepper.d.ts +13 -0
- package/dist/chat/ui/composer/use-effort-stepper.js +88 -0
- package/dist/chat/ui/composer/use-notice.js +61 -16
- package/dist/chat/ui/composer/use-pending-requests.js +38 -17
- package/dist/chat/ui/composer/use-prompt-history.js +117 -45
- package/dist/chat/ui/composer/use-prompt-hold.js +119 -35
- package/dist/chat/ui/composer/use-take-back.js +94 -72
- package/dist/chat/ui/diff/ApprovalReview.js +101 -23
- package/dist/chat/ui/diff/DiffFallbackBoundary.js +21 -13
- package/dist/chat/ui/diff/DiffOmitted.js +56 -6
- package/dist/chat/ui/diff/DiffStack.js +92 -8
- package/dist/chat/ui/diff/DiffUnavailable.js +56 -6
- package/dist/chat/ui/diff/EditorEditDiff.js +263 -51
- package/dist/chat/ui/diff/EditorPatchDiff.js +39 -14
- package/dist/chat/ui/diff/LegacyDiffPool.js +27 -10
- package/dist/chat/ui/diff/LegacyEditDiff.js +97 -20
- package/dist/chat/ui/diff/LegacyUnifiedDiff.js +172 -42
- package/dist/chat/ui/diff/RawDiff.js +65 -5
- package/dist/chat/ui/diff/ReviewDiff.js +77 -5
- package/dist/chat/ui/diff/diff-props.js +1 -1
- package/dist/chat/ui/diff/diff-source-budget.js +46 -35
- package/dist/chat/ui/diff/editor-edit-model.js +18 -14
- package/dist/chat/ui/diff/review-plan.js +63 -40
- package/dist/chat/ui/diff/review-settle.js +24 -9
- package/dist/chat/ui/diff/syntax-runtime.js +236 -201
- package/dist/chat/ui/diff/use-review-stack.js +146 -25
- package/dist/chat/ui/diff-syntax.js +70 -58
- package/dist/chat/ui/diff-theme.js +31 -12
- package/dist/chat/ui/file-links.js +39 -10
- package/dist/chat/ui/find-reveal.js +29 -8
- package/dist/chat/ui/full-diff.js +17 -12
- package/dist/chat/ui/highlighter.js +143 -113
- package/dist/chat/ui/icons.js +16 -7
- package/dist/chat/ui/index.js +1 -1
- package/dist/chat/ui/intelligent-ui/UiBlockFrame.js +556 -82
- package/dist/chat/ui/intelligent-ui/UiFallbackPart.js +73 -5
- package/dist/chat/ui/intelligent-ui/UiReply.js +666 -262
- package/dist/chat/ui/intelligent-ui/block-local.js +59 -31
- package/dist/chat/ui/intelligent-ui/chart-data.js +77 -67
- package/dist/chat/ui/intelligent-ui/node-text.js +77 -91
- package/dist/chat/ui/intelligent-ui/registry.js +46 -46
- package/dist/chat/ui/intelligent-ui/render-context.js +1 -1
- package/dist/chat/ui/intelligent-ui/renderers/base-land.js +1 -1
- package/dist/chat/ui/intelligent-ui/renderers/binding.js +3 -3
- package/dist/chat/ui/intelligent-ui/renderers/chart.js +1223 -123
- package/dist/chat/ui/intelligent-ui/renderers/choices.js +312 -34
- package/dist/chat/ui/intelligent-ui/renderers/content.js +1241 -86
- package/dist/chat/ui/intelligent-ui/renderers/data.js +619 -54
- package/dist/chat/ui/intelligent-ui/renderers/inputs.js +868 -67
- package/dist/chat/ui/intelligent-ui/renderers/links.js +366 -62
- package/dist/chat/ui/intelligent-ui/renderers/map-slots.js +118 -60
- package/dist/chat/ui/intelligent-ui/renderers/map-style.js +85 -78
- package/dist/chat/ui/intelligent-ui/renderers/map-view.js +282 -217
- package/dist/chat/ui/intelligent-ui/renderers/map.js +621 -69
- package/dist/chat/ui/intelligent-ui/renderers/place-point.js +15 -8
- package/dist/chat/ui/intelligent-ui/renderers/structure.js +262 -20
- package/dist/chat/ui/intelligent-ui/renderers/text.js +674 -49
- package/dist/chat/ui/intelligent-ui/reply-parts.js +24 -15
- package/dist/chat/ui/intelligent-ui/table-data.js +97 -57
- package/dist/chat/ui/intelligent-ui/tones.js +31 -31
- package/dist/chat/ui/intelligent-ui/use-in-view.js +30 -12
- package/dist/chat/ui/intelligent-ui/use-later.js +28 -13
- package/dist/chat/ui/intelligent-ui/use-truncated.js +45 -21
- package/dist/chat/ui/intelligent-ui/use-ui-links.js +296 -109
- package/dist/chat/ui/intelligent-ui/use-ui-queries.js +256 -246
- package/dist/chat/ui/markdown-blocks.js +296 -262
- package/dist/chat/ui/mermaid.d.ts +8 -20
- package/dist/chat/ui/mermaid.js +47 -84
- package/dist/chat/ui/quote-selection.js +32 -29
- package/dist/chat/ui/rehype-chips.js +35 -23
- package/dist/chat/ui/rehype-fade.js +28 -17
- package/dist/chat/ui/remark-html-as-text.js +22 -15
- package/dist/chat/ui/reply-context.js +1 -1
- package/dist/chat/ui/reveal.js +161 -72
- package/dist/chat/ui/rows/ForksRow.js +226 -24
- package/dist/chat/ui/rows/GeneratedImageRow.js +541 -87
- package/dist/chat/ui/rows/MessageRows.js +1706 -159
- package/dist/chat/ui/rows/RowContainer.js +57 -7
- package/dist/chat/ui/rows/Rows.js +463 -54
- package/dist/chat/ui/rows/SubagentRow.js +577 -60
- package/dist/chat/ui/rows/TaskRow.js +359 -40
- package/dist/chat/ui/rows/VisualRow.js +233 -11
- package/dist/chat/ui/rows/WorkRows.d.ts +3 -0
- package/dist/chat/ui/rows/WorkRows.js +1945 -164
- package/dist/chat/ui/rows/WorkflowRow.js +756 -37
- package/dist/chat/ui/rows/row-rhythm.js +27 -17
- package/dist/chat/ui/theme-watch.js +26 -23
- package/dist/chat/ui/timestamp-format.js +4 -1
- package/dist/chat/ui/use-diff-source-tokens.js +70 -34
- package/dist/chat/ui/useToggleSet.js +51 -19
- package/dist/chat/ui/visual-theme.js +153 -128
- package/dist/chat/visual-bridge.js +123 -123
- package/dist/chat/visual-viewport.js +94 -83
- package/dist/chat/visuals.js +13 -5
- package/dist/host-hooks.d.ts +29 -0
- package/dist/host-hooks.js +78 -0
- package/dist/host.js +120 -48
- package/dist/index.js +1 -1
- package/dist/lazy.js +38 -32
- package/dist/locales/en/agent-chat.d.ts +42 -0
- package/dist/locales/en/agent-chat.js +755 -713
- package/dist/locales/en/agent-prompts.js +42 -42
- package/dist/locales/en/agent-providers.d.ts +1 -0
- package/dist/locales/en/agent-providers.js +166 -165
- package/dist/locales/en/agent-usage.d.ts +6 -0
- package/dist/locales/en/agent-usage.js +129 -123
- package/dist/locales/nl/agent-chat.d.ts +42 -0
- package/dist/locales/nl/agent-chat.js +755 -713
- package/dist/locales/nl/agent-prompts.js +42 -42
- package/dist/locales/nl/agent-providers.d.ts +1 -0
- package/dist/locales/nl/agent-providers.js +166 -165
- package/dist/locales/nl/agent-usage.d.ts +6 -0
- package/dist/locales/nl/agent-usage.js +129 -123
- package/dist/locales.js +14 -14
- package/dist/mounted-registry.js +31 -30
- package/dist/port-transport.js +122 -111
- package/dist/prompts/index.js +1 -1
- package/dist/prompts/logic/focus.js +15 -14
- package/dist/prompts/logic/keys.js +93 -59
- package/dist/prompts/logic/prompts.js +27 -14
- package/dist/prompts/logic/subjects.js +60 -46
- package/dist/prompts/logic/useFocusAfterAnswer.js +60 -20
- package/dist/prompts/logic/usePromptSession.js +88 -77
- package/dist/prompts/ui/ApprovalBody.js +246 -27
- package/dist/prompts/ui/PromptActions.js +215 -9
- package/dist/prompts/ui/PromptCard.js +215 -36
- package/dist/prompts/ui/PromptView.js +372 -34
- package/dist/prompts/ui/QuestionBody.js +269 -73
- package/dist/providers/AccountColors.js +36 -5
- package/dist/providers/AccountDetail.js +683 -50
- package/dist/providers/AccountVariables.js +139 -32
- package/dist/providers/AddAccountForm.js +125 -38
- package/dist/providers/CliDetail.js +343 -36
- package/dist/providers/InstallPage.js +644 -59
- package/dist/providers/ProviderList.d.ts +2 -1
- package/dist/providers/ProviderList.js +215 -23
- package/dist/providers/ProvidersPane.d.ts +4 -2
- package/dist/providers/ProvidersPane.js +244 -64
- package/dist/providers/account-actions.js +54 -30
- package/dist/providers/index.js +1 -1
- package/dist/providers/install-steps.js +12 -9
- package/dist/providers/pane-target.d.ts +3 -0
- package/dist/providers/pane-target.js +34 -13
- package/dist/providers/parts.js +62 -12
- package/dist/providers/provider-abilities.js +5 -5
- package/dist/providers/provider-groups.js +75 -40
- package/dist/providers/variables.js +73 -39
- package/dist/scope.js +6 -6
- package/dist/settings/sections.js +18 -18
- package/dist/state/chats.js +404 -192
- package/dist/state/index.js +1 -1
- package/dist/state/provider-accounts.js +70 -47
- package/dist/state/providers.js +45 -16
- package/dist/state/usage.js +154 -77
- package/dist/storage.js +69 -68
- package/dist/testing/index.js +1 -1
- package/dist/testing/prompts.js +105 -67
- package/dist/transport.js +10 -10
- package/dist/ui/PlainTextarea.js +27 -3
- package/dist/usage/LimitsList.js +646 -40
- package/dist/usage/UsageBreakdown.js +879 -38
- package/dist/usage/UsageChart.js +311 -32
- package/dist/usage/UsageDialog.js +46 -4
- package/dist/usage/UsageLimits.js +467 -34
- package/dist/usage/UsageLimitsCard.js +95 -11
- package/dist/usage/UsagePage.js +817 -96
- package/dist/usage/UsagePane.js +164 -10
- package/dist/usage/UsageSummary.js +151 -6
- package/dist/usage/UsageTiles.js +164 -14
- package/dist/usage/format.js +32 -32
- package/dist/usage/index.d.ts +1 -1
- package/dist/usage/index.js +2 -1
- package/dist/usage/limit-groups.d.ts +2 -0
- package/dist/usage/limit-groups.js +77 -59
- package/dist/usage/limits.js +78 -43
- package/dist/usage/money.js +20 -4
- package/dist/usage/summary.js +85 -64
- package/package.json +9 -9
- package/src/agents/ModelOptionControl.tsx +3 -1
- package/src/agents/option-words.ts +27 -0
- package/src/chat/account-choice.ts +41 -1
- package/src/chat/composer-effort.ts +32 -0
- package/src/chat/forks.ts +4 -5
- package/src/chat/index.ts +3 -1
- package/src/chat/logic/effort.ts +32 -0
- package/src/chat/logic/picker-entries.ts +45 -10
- package/src/chat/logic/resume-compaction.ts +95 -17
- package/src/chat/logic/timeline.ts +11 -3
- package/src/chat/logic/workflow.ts +86 -4
- package/src/chat/preferences.ts +35 -0
- package/src/chat/subagent-view.ts +2 -3
- package/src/chat/ui/AnsiOutput.tsx +1 -2
- package/src/chat/ui/BookmarkSubmenu.tsx +3 -3
- package/src/chat/ui/ChatActivity.tsx +14 -22
- package/src/chat/ui/ChatReferenceChip.tsx +2 -3
- package/src/chat/ui/Composer.tsx +15 -7
- package/src/chat/ui/EditDiff.tsx +2 -3
- package/src/chat/ui/LimitState.tsx +2 -2
- package/src/chat/ui/Markdown.tsx +10 -8
- package/src/chat/ui/MermaidBlock.tsx +57 -49
- package/src/chat/ui/Pickers.tsx +49 -29
- package/src/chat/ui/PromptComposer.tsx +7 -9
- package/src/chat/ui/ResumeCompactionDock.tsx +16 -4
- package/src/chat/ui/RunSettings.tsx +67 -28
- package/src/chat/ui/Scrubber.tsx +3 -3
- package/src/chat/ui/ShellCommand.tsx +2 -0
- package/src/chat/ui/SubagentInfo.tsx +2 -3
- package/src/chat/ui/SubagentTimeline.tsx +12 -16
- package/src/chat/ui/Timeline.tsx +6 -6
- package/src/chat/ui/UnifiedDiff.tsx +3 -4
- package/src/chat/ui/VisualFrame.tsx +5 -8
- package/src/chat/ui/code-theme.ts +4 -4
- package/src/chat/ui/composer/placeholder.ts +2 -2
- package/src/chat/ui/composer/use-compaction-offer.ts +36 -16
- package/src/chat/ui/composer/use-composer-menus.ts +4 -9
- package/src/chat/ui/composer/use-composer-submit.ts +2 -1
- package/src/chat/ui/composer/use-effort-stepper.ts +56 -0
- package/src/chat/ui/composer/use-notice.ts +2 -2
- package/src/chat/ui/diff/EditorEditDiff.tsx +9 -13
- package/src/chat/ui/diff/LegacyEditDiff.tsx +12 -17
- package/src/chat/ui/diff/LegacyUnifiedDiff.tsx +13 -21
- package/src/chat/ui/diff/use-review-stack.ts +4 -4
- package/src/chat/ui/diff-theme.ts +3 -3
- package/src/chat/ui/file-links.ts +2 -2
- package/src/chat/ui/intelligent-ui/UiReply.tsx +2 -0
- package/src/chat/ui/intelligent-ui/renderers/chart.tsx +3 -3
- package/src/chat/ui/intelligent-ui/renderers/content.tsx +5 -6
- package/src/chat/ui/intelligent-ui/renderers/map-view.tsx +2 -1
- package/src/chat/ui/intelligent-ui/renderers/map.tsx +2 -1
- package/src/chat/ui/intelligent-ui/use-truncated.ts +16 -19
- package/src/chat/ui/intelligent-ui/use-ui-links.ts +3 -3
- package/src/chat/ui/mermaid.ts +52 -96
- package/src/chat/ui/rows/ForksRow.tsx +3 -5
- package/src/chat/ui/rows/GeneratedImageRow.tsx +2 -1
- package/src/chat/ui/rows/MessageRows.tsx +12 -21
- package/src/chat/ui/rows/SubagentRow.tsx +3 -3
- package/src/chat/ui/rows/TaskRow.tsx +1 -1
- package/src/chat/ui/rows/WorkRows.tsx +11 -6
- package/src/chat/ui/rows/WorkflowRow.tsx +144 -54
- package/src/chat/ui/useToggleSet.ts +15 -18
- package/src/chat/ui/visual-theme.ts +2 -3
- package/src/host-hooks.ts +113 -0
- package/src/lazy.tsx +2 -0
- package/src/locales/en/agent-chat.ts +142 -108
- package/src/locales/en/agent-prompts.ts +7 -7
- package/src/locales/en/agent-providers.ts +35 -34
- package/src/locales/en/agent-usage.ts +26 -20
- package/src/locales/nl/agent-chat.ts +134 -100
- package/src/locales/nl/agent-prompts.ts +5 -5
- package/src/locales/nl/agent-providers.ts +33 -32
- package/src/locales/nl/agent-usage.ts +25 -20
- package/src/providers/CliDetail.tsx +2 -1
- package/src/providers/InstallPage.tsx +2 -4
- package/src/providers/ProviderList.tsx +12 -2
- package/src/providers/ProvidersPane.tsx +45 -15
- package/src/providers/pane-target.ts +20 -4
- package/src/state/chats.ts +2 -2
- package/src/usage/LimitsList.tsx +12 -13
- package/src/usage/UsageBreakdown.tsx +17 -6
- package/src/usage/UsageLimits.tsx +2 -1
- package/src/usage/UsagePage.tsx +3 -3
- package/src/usage/index.ts +1 -1
- package/src/usage/limit-groups.ts +12 -0
- package/src/usage/limits.ts +2 -2
- package/src/usage/money.ts +1 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useContext,
|
|
1
|
+
import { useContext, useState, type ReactNode } from 'react';
|
|
2
2
|
import clsx from 'clsx';
|
|
3
3
|
import { useTranslation } from 'react-i18next';
|
|
4
4
|
import { Bot, Brain, Check, ChevronDown, CircleAlert, File, Info, MessageCircleQuestionMark, Reply, TriangleAlert, X } from 'lucide-react';
|
|
@@ -14,7 +14,6 @@ import type {
|
|
|
14
14
|
import { WAITING_NOTE_PREFIX } from '@adecore/agent-contracts';
|
|
15
15
|
import { fileBadge, formatBytes, isImageAttachment } from '../../attachments';
|
|
16
16
|
import { useChatRow, useCurrentItem } from '../../../state/chats';
|
|
17
|
-
import { useChatHost } from '../../../host';
|
|
18
17
|
import { useChatScope } from '../../../scope';
|
|
19
18
|
import { splitQuote } from '../../quote';
|
|
20
19
|
import { jumpToTimelineItem } from '../../timeline-scroll';
|
|
@@ -34,6 +33,7 @@ import { ROW_GUTTER } from '../icons';
|
|
|
34
33
|
import { useOpenForFind } from '../find-reveal';
|
|
35
34
|
import { ReplyContext, UiReplyNavigationContext } from '../reply-context';
|
|
36
35
|
import { UiReply } from '../intelligent-ui/UiReply';
|
|
36
|
+
import { useHostAttachmentUrl, useHostChatPlace, useHostReplyAuthor, useHostStreaming } from '../../../host-hooks';
|
|
37
37
|
|
|
38
38
|
// A long prompt folds so the answer stays in view; the reader can open it.
|
|
39
39
|
const USER_FOLD_LINES = 8;
|
|
@@ -43,10 +43,9 @@ const USER_FOLD_CHARS = 600;
|
|
|
43
43
|
const FOLD = 'max-h-[10em] overflow-hidden [mask-image:linear-gradient(to_bottom,black_70%,transparent)]';
|
|
44
44
|
|
|
45
45
|
function useReplyAuthor(chatId: string) {
|
|
46
|
-
const host = useChatHost();
|
|
47
46
|
const { id } = useChatScope();
|
|
48
47
|
const context = useContext(ReplyContext);
|
|
49
|
-
const author =
|
|
48
|
+
const author = useHostReplyAuthor(id, context?.chatId ?? chatId);
|
|
50
49
|
return context !== null && context.chatId === undefined ? null : author;
|
|
51
50
|
}
|
|
52
51
|
|
|
@@ -55,9 +54,8 @@ function useReplyAuthor(chatId: string) {
|
|
|
55
54
|
* hands a link that opens a window to the system browser, which cannot reach a blob of this page.
|
|
56
55
|
*/
|
|
57
56
|
function AttachmentLink({ chatId, attachment }: { chatId: string; attachment: ChatAttachment }) {
|
|
58
|
-
const host = useChatHost();
|
|
59
57
|
const { id } = useChatScope();
|
|
60
|
-
const { url } =
|
|
58
|
+
const { url } = useHostAttachmentUrl(id, chatId, attachment.id);
|
|
61
59
|
const badge = fileBadge(attachment.name);
|
|
62
60
|
return (
|
|
63
61
|
<Tooltip label={attachment.name}>
|
|
@@ -81,9 +79,8 @@ function AttachmentLink({ chatId, attachment }: { chatId: string; attachment: Ch
|
|
|
81
79
|
|
|
82
80
|
/* A picture attached to a message, which opens large. */
|
|
83
81
|
function AttachmentThumb({ chatId, attachment }: { chatId: string; attachment: ChatAttachment }) {
|
|
84
|
-
const host = useChatHost();
|
|
85
82
|
const { id } = useChatScope();
|
|
86
|
-
const source =
|
|
83
|
+
const source = useHostAttachmentUrl(id, chatId, attachment.id);
|
|
87
84
|
return <ImageThumb source={source} alt={attachment.name} className="max-h-32 max-w-48 object-cover" />;
|
|
88
85
|
}
|
|
89
86
|
|
|
@@ -268,15 +265,11 @@ function Writing() {
|
|
|
268
265
|
* written fades anything: an old reply scrolled back into view just stands there.
|
|
269
266
|
*/
|
|
270
267
|
export function AssistantRow({ chatId, item: derived }: { chatId: string; item: ChatAssistantItem }) {
|
|
271
|
-
const host = useChatHost();
|
|
272
268
|
const item = useCurrentItem(chatId, derived);
|
|
273
269
|
const scope = useChatScope();
|
|
274
270
|
const context = useContext(ReplyContext);
|
|
275
|
-
const reply =
|
|
276
|
-
|
|
277
|
-
[context, item.parentToolUseId, scope.id, chatId, item.id, item.streaming]
|
|
278
|
-
);
|
|
279
|
-
const mode = host.useStreaming();
|
|
271
|
+
const reply = context === null && !item.parentToolUseId ? { scopeId: scope.id, chatId, itemId: item.id, streaming: item.streaming } : undefined;
|
|
272
|
+
const mode = useHostStreaming();
|
|
280
273
|
const [sawWriting] = useState(item.streaming);
|
|
281
274
|
const live = mode === 'words' && item.streaming;
|
|
282
275
|
const reveal = useRevealedText(item.text, live);
|
|
@@ -338,10 +331,9 @@ export function AssistantRow({ chatId, item: derived }: { chatId: string; item:
|
|
|
338
331
|
* folded, it shows the heading it opens with or itself on one line, and opened, it reads as Markdown.
|
|
339
332
|
*/
|
|
340
333
|
export function ThinkingRow({ chatId, item: derived }: { chatId: string; item: ChatThinkingItem }) {
|
|
341
|
-
const host = useChatHost();
|
|
342
334
|
const { t } = useTranslation('agent-chat');
|
|
343
335
|
const item = useCurrentItem(chatId, derived);
|
|
344
|
-
const mode =
|
|
336
|
+
const mode = useHostStreaming();
|
|
345
337
|
const [open, setOpen] = useState(false);
|
|
346
338
|
const reveal = useRevealedText(item.text, mode === 'words' && item.streaming);
|
|
347
339
|
// A block at a time, the paragraphs of the thought that closed are shown as they land.
|
|
@@ -349,8 +341,8 @@ export function ThinkingRow({ chatId, item: derived }: { chatId: string; item: C
|
|
|
349
341
|
// Whole, the thought stays behind "Thinking…" until it is done and then folds like any other.
|
|
350
342
|
const shown = open || reveal.active || (settled !== null && settled !== '');
|
|
351
343
|
const text = settled ?? reveal.text;
|
|
352
|
-
const live =
|
|
353
|
-
const preview =
|
|
344
|
+
const live = item.streaming && mode !== 'whole' ? thoughtLine(text) : '';
|
|
345
|
+
const preview = item.streaming ? '' : thoughtPreview(item.text);
|
|
354
346
|
const duration = formatElapsedShort((item.endedAt ?? item.createdAt) - item.createdAt);
|
|
355
347
|
useOpenForFind(item.id, 'text', setOpen);
|
|
356
348
|
return (
|
|
@@ -401,7 +393,7 @@ export function ThinkingRow({ chatId, item: derived }: { chatId: string; item: C
|
|
|
401
393
|
*/
|
|
402
394
|
export function LiveThoughtRow({ chatId, item: derived }: { chatId: string; item: ChatThinkingItem }) {
|
|
403
395
|
const item = useCurrentItem(chatId, derived);
|
|
404
|
-
const line =
|
|
396
|
+
const line = thoughtLine(item.text);
|
|
405
397
|
if (line === '') {
|
|
406
398
|
return null;
|
|
407
399
|
}
|
|
@@ -465,9 +457,8 @@ export function NoteRow({ id, level, text, from }: { id: string; level: 'info' |
|
|
|
465
457
|
|
|
466
458
|
/* "Open fork" on a note a fork sent, or "Open to answer" on one about a waiting child, while that chat is still in the project. */
|
|
467
459
|
function OpenChatButton({ chatId, label }: { chatId: string; label: 'openFork' | 'openWaiting' }) {
|
|
468
|
-
const host = useChatHost();
|
|
469
460
|
const { t } = useTranslation('agent-chat');
|
|
470
|
-
const place =
|
|
461
|
+
const place = useHostChatPlace(chatId);
|
|
471
462
|
if (place.title === null) {
|
|
472
463
|
return null;
|
|
473
464
|
}
|
|
@@ -15,9 +15,10 @@ import { RunningFor, ToggleLine, WorkLiveRow, WorkRow } from './WorkRows';
|
|
|
15
15
|
import { entryTimeOf, statusWordOf, taskIdOf } from '../../subagent-list';
|
|
16
16
|
import { useSubagentSupport } from '../../subagent-support';
|
|
17
17
|
import { canOpenSubagent, crumbOf, type SubagentStep } from '../../subagent-view';
|
|
18
|
-
import {
|
|
18
|
+
import { type SubagentTask } from '../../../host';
|
|
19
19
|
import { useChatScope } from '../../../scope';
|
|
20
20
|
import { useCurrentItem } from '../../../state/chats';
|
|
21
|
+
import { useHostTask } from '../../../host-hooks';
|
|
21
22
|
|
|
22
23
|
// The work of a long-running agent scrolls inside its row instead of pushing the thread away.
|
|
23
24
|
const CHILDREN_MAX_PX = 320;
|
|
@@ -135,11 +136,10 @@ export function SubagentRow({
|
|
|
135
136
|
/* Opens everything it did in the thread's place, for a surface that has somewhere to open it. */
|
|
136
137
|
onOpenConversation?(): void;
|
|
137
138
|
}) {
|
|
138
|
-
const host = useChatHost();
|
|
139
139
|
const { t } = useTranslation('agent-chat');
|
|
140
140
|
const { id } = useChatScope();
|
|
141
141
|
const taskId = taskIdOf(item);
|
|
142
|
-
const task =
|
|
142
|
+
const task = useHostTask(id, taskId);
|
|
143
143
|
// A task paused on its child's limit is still a running row on the wire, but nothing is at work.
|
|
144
144
|
const running = item.status === 'running' && statusWordOf(item, task) !== 'paused';
|
|
145
145
|
const detail = item.description || item.summary || item.subagentType || '';
|
|
@@ -39,7 +39,7 @@ function Elapsed({ startedAt }: { startedAt: number }) {
|
|
|
39
39
|
function StateLine({ state, task }: { state: TaskRowState; task: SubagentTask | null }) {
|
|
40
40
|
const { t } = useTranslation('agent-chat');
|
|
41
41
|
const until = state === 'paused' ? task?.paused?.until : undefined;
|
|
42
|
-
const now = useNow(60_000, until
|
|
42
|
+
const now = useNow(60_000, until !== undefined);
|
|
43
43
|
return (
|
|
44
44
|
<span className={clsx('truncate text-2xs', STATE_TONE[state])}>
|
|
45
45
|
{until === undefined ? t(`rows.task.${state}`) : t('rows.task.pausedUntil', { time: formatMoment(until, now) })}
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
} from '../../logic/tools';
|
|
24
24
|
import { useOpenForFind } from '../find-reveal';
|
|
25
25
|
import { useChatHost, type CommandLook } from '../../../host';
|
|
26
|
+
import { useCommandNames } from '../../../host-hooks';
|
|
26
27
|
import { lazyNamed } from '../../../lazy';
|
|
27
28
|
import { useChatActions } from '../../actions';
|
|
28
29
|
import { ChatScopeContext, useChatScope } from '../../../scope';
|
|
@@ -71,10 +72,14 @@ function withBrand(text: string, brands: readonly string[]): ReactNode {
|
|
|
71
72
|
return text;
|
|
72
73
|
}
|
|
73
74
|
|
|
75
|
+
function hasNames(look: CommandLook): look is CommandLook & Required<Pick<CommandLook, 'useNames'>> {
|
|
76
|
+
return look.useNames !== undefined;
|
|
77
|
+
}
|
|
78
|
+
|
|
74
79
|
/* The detail of a look's run, with the words its host names drawn as those names. */
|
|
75
|
-
function NamedLookDetail({ run, chatId,
|
|
80
|
+
function NamedLookDetail({ run, chatId, look }: { run: CommandLookRun; chatId: string; look: Required<Pick<CommandLook, 'useNames'>> }) {
|
|
76
81
|
const scope = useContext(ChatScopeContext);
|
|
77
|
-
const nameOf =
|
|
82
|
+
const nameOf = useCommandNames(look, scope?.id ?? '', chatId);
|
|
78
83
|
const names = run.words.flatMap((word): NamedWord[] => {
|
|
79
84
|
const name = nameOf(word.text, word.option);
|
|
80
85
|
return name === null ? [] : [{ start: word.start, end: word.end, word: word.text, name }];
|
|
@@ -83,12 +88,12 @@ function NamedLookDetail({ run, chatId, useNames }: { run: CommandLookRun; chatI
|
|
|
83
88
|
}
|
|
84
89
|
|
|
85
90
|
function LookDetail({ run, chatId }: { run: CommandLookRun; chatId: string }) {
|
|
86
|
-
const {
|
|
87
|
-
if (
|
|
91
|
+
const { look } = run;
|
|
92
|
+
if (!hasNames(look)) {
|
|
88
93
|
return <ShellCommand command={run.detail} code={run.code} />;
|
|
89
94
|
}
|
|
90
95
|
// Keyed by the look, so a row whose command turns into another look's starts its hooks again.
|
|
91
|
-
return <NamedLookDetail key={
|
|
96
|
+
return <NamedLookDetail key={look.program} run={run} chatId={chatId} look={look} />;
|
|
92
97
|
}
|
|
93
98
|
|
|
94
99
|
const TAG = 'shrink-0 rounded bg-surface-hover px-1.5 text-text-faint';
|
|
@@ -278,7 +283,7 @@ function ToolOutput({ tool }: { tool: ChatToolItem }) {
|
|
|
278
283
|
}
|
|
279
284
|
|
|
280
285
|
/* An opened call without a card: what it was asked in the foreground, what it answered muted below. */
|
|
281
|
-
function ToolBody({ tool }: { tool: ChatToolItem }) {
|
|
286
|
+
export function ToolBody({ tool }: { tool: ChatToolItem }) {
|
|
282
287
|
const patches = unifiedChanges(tool);
|
|
283
288
|
const changes = patches.length > 0 ? [] : fileChanges(tool.name, tool.input);
|
|
284
289
|
if (patches.length + changes.length > 0) {
|
|
@@ -1,68 +1,129 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import clsx from 'clsx';
|
|
1
3
|
import { useTranslation } from 'react-i18next';
|
|
2
|
-
import { Bot,
|
|
3
|
-
import { workflowAgentRef, type ChatToolItem, type ChatWorkflow } from '@adecore/agent-contracts';
|
|
4
|
-
import {
|
|
4
|
+
import { Bot, ChevronRight, Square, TriangleAlert, Workflow, X } from 'lucide-react';
|
|
5
|
+
import { workflowAgentRef, type AgentKind, type ChatToolItem, type ChatWorkflow } from '@adecore/agent-contracts';
|
|
6
|
+
import { formatElapsedShort } from '@adecore/ui/format';
|
|
7
|
+
import { Icon, IconButton, useTickingText } from '@adecore/ui';
|
|
8
|
+
import { AgentIcon } from '../../../agents/AgentIcon';
|
|
9
|
+
import {
|
|
10
|
+
workflowAgentPreview,
|
|
11
|
+
workflowAgentTime,
|
|
12
|
+
workflowCounts,
|
|
13
|
+
workflowDescription,
|
|
14
|
+
workflowPhases,
|
|
15
|
+
type WorkflowAgentState,
|
|
16
|
+
type WorkflowAgentView,
|
|
17
|
+
type WorkflowCounts,
|
|
18
|
+
type WorkflowPhaseView
|
|
19
|
+
} from '../../logic/workflow';
|
|
20
|
+
import { hasToolBody } from '../../logic/tools';
|
|
5
21
|
import { useSubagentSupport } from '../../subagent-support';
|
|
6
22
|
import type { SubagentStep } from '../../subagent-view';
|
|
7
23
|
import { ROW_GUTTER } from '../icons';
|
|
8
|
-
import {
|
|
24
|
+
import { ToolBody } from './WorkRows';
|
|
9
25
|
import { useChatScope } from '../../../scope';
|
|
10
|
-
import {
|
|
26
|
+
import { useChats } from '../../../state/chats';
|
|
11
27
|
import { useChatActions } from '../../actions';
|
|
12
28
|
import { useChatHost } from '../../../host';
|
|
13
29
|
|
|
14
|
-
|
|
30
|
+
const DOT: Record<WorkflowAgentState, string> = {
|
|
31
|
+
running: 'bg-status-running',
|
|
32
|
+
waiting: 'bg-text-faint',
|
|
33
|
+
stopped: 'bg-text-faint',
|
|
34
|
+
done: 'bg-status-idle',
|
|
35
|
+
failed: 'bg-status-error'
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const TIME = 'shrink-0 text-xs text-text-faint tabular-nums';
|
|
39
|
+
|
|
40
|
+
function Elapsed({ startedAt }: { startedAt: number }) {
|
|
41
|
+
const ref = useTickingText(() => formatElapsedShort(Date.now() - startedAt));
|
|
42
|
+
return <span ref={ref} className={TIME} />;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function AgentLine({ view, provider, onOpen }: { view: WorkflowAgentView; provider: AgentKind | undefined; onOpen?(step: SubagentStep): void }) {
|
|
15
46
|
const { agent, state } = view;
|
|
16
47
|
const time = workflowAgentTime(view);
|
|
17
|
-
const
|
|
48
|
+
const preview = workflowAgentPreview(view);
|
|
18
49
|
const agentId = agent.agentId;
|
|
19
50
|
// One still waiting has no transcript yet.
|
|
20
|
-
const open = onOpen !== undefined && agentId !== null ? () => onOpen({ toolUseId: workflowAgentRef(agentId), description: agent.label }) :
|
|
51
|
+
const open = onOpen !== undefined && agentId !== null ? () => onOpen({ toolUseId: workflowAgentRef(agentId), description: agent.label }) : undefined;
|
|
21
52
|
return (
|
|
22
|
-
<
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
53
|
+
<button
|
|
54
|
+
className="-mx-1 mb-0.5 flex w-[calc(100%+8px)] items-start gap-2 rounded-md px-1 py-1 text-left enabled:hover:bg-surface-hover"
|
|
55
|
+
disabled={open === undefined}
|
|
56
|
+
onClick={open}
|
|
57
|
+
>
|
|
58
|
+
<span className={clsx(ROW_GUTTER, 'relative text-text')}>
|
|
59
|
+
{provider === undefined ? <Icon icon={Bot} size={14} /> : <AgentIcon kind={provider} size={14} />}
|
|
60
|
+
<span className={clsx('absolute -right-0.75 bottom-0 size-2 rounded-full ring-2 ring-surface', DOT[state])} />
|
|
61
|
+
</span>
|
|
62
|
+
<span className="flex min-w-0 grow flex-col">
|
|
63
|
+
<span data-find-field="summary" className={clsx('truncate text-xs font-medium', state === 'failed' ? 'text-status-error' : 'text-text')}>
|
|
64
|
+
{agent.label}
|
|
65
|
+
</span>
|
|
66
|
+
{(preview.tool !== null || preview.text !== null) && (
|
|
67
|
+
<span className="truncate text-2xs text-text-muted">
|
|
68
|
+
{preview.tool !== null && <span className="font-mono text-code">{preview.tool}</span>}
|
|
69
|
+
{preview.tool !== null && preview.text !== null && ' · '}
|
|
70
|
+
{preview.text}
|
|
71
|
+
</span>
|
|
72
|
+
)}
|
|
73
|
+
</span>
|
|
74
|
+
<span className="flex h-5 shrink-0 items-center gap-2">
|
|
75
|
+
{state === 'running' && agent.startedAt !== null ? (
|
|
76
|
+
<Elapsed startedAt={agent.startedAt} />
|
|
33
77
|
) : (
|
|
34
|
-
<span className=
|
|
35
|
-
)
|
|
36
|
-
|
|
37
|
-
|
|
78
|
+
time !== null && <span className={TIME}>{time}</span>
|
|
79
|
+
)}
|
|
80
|
+
{state === 'failed' && <Icon icon={X} size={12} className="shrink-0 text-status-error" />}
|
|
81
|
+
<Icon icon={ChevronRight} size={12} className={clsx('shrink-0 text-text-faint', open === undefined && 'invisible')} />
|
|
82
|
+
</span>
|
|
83
|
+
</button>
|
|
38
84
|
);
|
|
39
85
|
}
|
|
40
86
|
|
|
41
|
-
function PhaseBlock({ phase, onOpen }: { phase: WorkflowPhaseView; onOpen?(step: SubagentStep): void }) {
|
|
87
|
+
function PhaseBlock({ phase, provider, onOpen }: { phase: WorkflowPhaseView; provider: AgentKind | undefined; onOpen?(step: SubagentStep): void }) {
|
|
42
88
|
const { t } = useTranslation('agent-chat');
|
|
89
|
+
const settled = phase.agents.filter((view) => view.state === 'done' || view.state === 'failed').length;
|
|
43
90
|
return (
|
|
44
|
-
<div>
|
|
91
|
+
<div className="mt-3">
|
|
45
92
|
{phase.title !== null && (
|
|
46
|
-
<div className="
|
|
47
|
-
<span className={
|
|
48
|
-
|
|
93
|
+
<div className="flex h-7 min-w-0 items-center gap-2 text-xs">
|
|
94
|
+
<span className="min-w-0 truncate font-medium text-text">{phase.title}</span>
|
|
95
|
+
<span className="shrink-0 text-text-faint tabular-nums">
|
|
96
|
+
{phase.agents.length === 0 ? t('rows.workflow.notStarted') : `${settled}/${phase.agents.length}`}
|
|
49
97
|
</span>
|
|
50
|
-
<span className="min-w-0 truncate">{phase.title}</span>
|
|
51
|
-
<span className="grow" />
|
|
52
|
-
{phase.agents.length === 0 && <span className="shrink-0 text-text-faint">{t('rows.workflow.notStarted')}</span>}
|
|
53
|
-
</div>
|
|
54
|
-
)}
|
|
55
|
-
{phase.agents.length > 0 && (
|
|
56
|
-
<div className={phase.title === null ? undefined : 'ml-6'}>
|
|
57
|
-
{phase.agents.map((view) => (
|
|
58
|
-
<AgentLine key={view.agent.index} view={view} onOpen={onOpen} />
|
|
59
|
-
))}
|
|
60
98
|
</div>
|
|
61
99
|
)}
|
|
100
|
+
{phase.agents.map((view) => (
|
|
101
|
+
<AgentLine key={view.agent.index} view={view} provider={provider} onOpen={onOpen} />
|
|
102
|
+
))}
|
|
62
103
|
</div>
|
|
63
104
|
);
|
|
64
105
|
}
|
|
65
106
|
|
|
107
|
+
function Counts({ counts }: { counts: WorkflowCounts }) {
|
|
108
|
+
const { t } = useTranslation('agent-chat');
|
|
109
|
+
const parts = [
|
|
110
|
+
{ key: 'working', count: counts.running, tone: 'text-status-running' },
|
|
111
|
+
{ key: 'finished', count: counts.done, tone: 'text-status-idle' },
|
|
112
|
+
{ key: 'failedCount', count: counts.failed, tone: 'text-status-error' }
|
|
113
|
+
].filter((part) => part.count > 0);
|
|
114
|
+
return (
|
|
115
|
+
<span className="shrink-0 truncate text-xs text-text-faint tabular-nums">
|
|
116
|
+
{t('rows.workflow.agents', { count: counts.total })}
|
|
117
|
+
{parts.map((part) => (
|
|
118
|
+
<span key={part.key}>
|
|
119
|
+
{' · '}
|
|
120
|
+
<span className={part.tone}>{t(`rows.workflow.${part.key}`, { count: part.count })}</span>
|
|
121
|
+
</span>
|
|
122
|
+
))}
|
|
123
|
+
</span>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
66
127
|
// Keep background progress visible after the launcher turn ends.
|
|
67
128
|
export function WorkflowRow({
|
|
68
129
|
tool,
|
|
@@ -77,11 +138,16 @@ export function WorkflowRow({
|
|
|
77
138
|
}) {
|
|
78
139
|
const host = useChatHost();
|
|
79
140
|
const { t } = useTranslation('agent-chat');
|
|
80
|
-
const { id } = useChatScope();
|
|
141
|
+
const { id, keyOf } = useChatScope();
|
|
142
|
+
const [open, setOpen] = useState(false);
|
|
81
143
|
// A host that does not answer `chat.subagent` has no conversation to open for anyone.
|
|
82
144
|
const refused = useSubagentSupport((s) => s.unsupported[id] === true);
|
|
145
|
+
const provider = useChats((s) => (chatId === undefined ? undefined : s.statusByKey[keyOf(chatId)]?.info?.provider));
|
|
83
146
|
const running = tool.state === 'running';
|
|
84
147
|
const phases = workflowPhases(workflow, running);
|
|
148
|
+
const counts = workflowCounts(phases);
|
|
149
|
+
const description = workflowDescription(tool.input);
|
|
150
|
+
const opens = hasToolBody(tool);
|
|
85
151
|
const onOpen = refused ? undefined : onOpenAgent;
|
|
86
152
|
const actions = useChatActions();
|
|
87
153
|
const stop = (): void => {
|
|
@@ -95,27 +161,51 @@ export function WorkflowRow({
|
|
|
95
161
|
});
|
|
96
162
|
}
|
|
97
163
|
};
|
|
164
|
+
const failed = tool.state === 'error';
|
|
165
|
+
const header = (
|
|
166
|
+
<>
|
|
167
|
+
<span className={clsx(ROW_GUTTER, running && 'text-accent')}>
|
|
168
|
+
<Icon icon={Workflow} size={12} />
|
|
169
|
+
</span>
|
|
170
|
+
<span className={clsx('shrink-0', running && 'chat-live-text')}>{t(`rows.workflow.${running ? 'running' : failed ? 'failed' : 'done'}`)}</span>
|
|
171
|
+
<span className="grow" />
|
|
172
|
+
{counts.total > 0 && <Counts counts={counts} />}
|
|
173
|
+
{opens && <Icon icon={ChevronRight} size={12} className={clsx('shrink-0 text-text-faint transition-transform', open && 'rotate-90')} />}
|
|
174
|
+
</>
|
|
175
|
+
);
|
|
176
|
+
const headerClasses = clsx(
|
|
177
|
+
'-mx-1 flex h-7 w-[calc(100%+8px)] min-w-0 items-center gap-2 rounded-md px-1 text-left text-xs',
|
|
178
|
+
failed ? 'text-status-error' : 'text-text-muted',
|
|
179
|
+
opens && 'hover:bg-surface-hover'
|
|
180
|
+
);
|
|
98
181
|
return (
|
|
99
|
-
<div>
|
|
182
|
+
<div data-find-item={tool.id} className="mb-1">
|
|
100
183
|
<div className="flex items-center gap-1">
|
|
101
184
|
<div className="min-w-0 grow">
|
|
102
|
-
{
|
|
185
|
+
{opens ? (
|
|
186
|
+
<button className={headerClasses} onClick={() => setOpen((value) => !value)}>
|
|
187
|
+
{header}
|
|
188
|
+
</button>
|
|
189
|
+
) : (
|
|
190
|
+
<div className={headerClasses}>{header}</div>
|
|
191
|
+
)}
|
|
103
192
|
</div>
|
|
104
193
|
{running && chatId && workflow.taskId && <IconButton icon={Square} size="xs" label={t('activity.stop')} onClick={stop} />}
|
|
105
194
|
</div>
|
|
106
|
-
{
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
195
|
+
{open && opens && <ToolBody tool={tool} />}
|
|
196
|
+
<div className="mt-1.5 ml-6">
|
|
197
|
+
{workflow.name !== null && <div className="truncate text-sm font-medium text-text">{workflow.name}</div>}
|
|
198
|
+
{description !== null && <p className="mt-0.5 line-clamp-2 text-xs text-text-muted">{description}</p>}
|
|
199
|
+
{running && workflow.stalledAt !== undefined && (
|
|
200
|
+
<p role="status" className="mt-1 flex items-start gap-1.5 text-xs text-text-muted">
|
|
201
|
+
<Icon icon={TriangleAlert} size={12} className="mt-0.5 shrink-0 text-status-needs-you" />
|
|
202
|
+
<span>{t('rows.workflow.stalled')}</span>
|
|
203
|
+
</p>
|
|
204
|
+
)}
|
|
205
|
+
{phases.map((phase) => (
|
|
206
|
+
<PhaseBlock key={phase.key} phase={phase} provider={provider} onOpen={onOpen} />
|
|
207
|
+
))}
|
|
208
|
+
</div>
|
|
119
209
|
</div>
|
|
120
210
|
);
|
|
121
211
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useState } from 'react';
|
|
2
2
|
|
|
3
3
|
export interface ToggleSet {
|
|
4
4
|
ids: ReadonlySet<string>;
|
|
@@ -15,25 +15,22 @@ export interface ToggleSet {
|
|
|
15
15
|
export function useToggleSet(onToggle?: () => void): ToggleSet {
|
|
16
16
|
const [ids, setIds] = useState<ReadonlySet<string>>(() => new Set());
|
|
17
17
|
|
|
18
|
-
const toggle =
|
|
19
|
-
(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
},
|
|
31
|
-
[onToggle]
|
|
32
|
-
);
|
|
18
|
+
const toggle = (id: string): void => {
|
|
19
|
+
setIds((current) => {
|
|
20
|
+
const next = new Set(current);
|
|
21
|
+
if (next.has(id)) {
|
|
22
|
+
next.delete(id);
|
|
23
|
+
} else {
|
|
24
|
+
next.add(id);
|
|
25
|
+
}
|
|
26
|
+
return next;
|
|
27
|
+
});
|
|
28
|
+
onToggle?.();
|
|
29
|
+
};
|
|
33
30
|
|
|
34
|
-
const add =
|
|
31
|
+
const add = (id: string): void => {
|
|
35
32
|
setIds((current) => new Set(current).add(id));
|
|
36
|
-
}
|
|
33
|
+
};
|
|
37
34
|
|
|
38
35
|
return { ids, toggle, add };
|
|
39
36
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useLayoutEffect, useState, type RefObject } from 'react';
|
|
2
2
|
import { cleanVisualVariables, type VisualAppearance, type VisualTheme, type VisualThemeVariable } from '@adecore/agent-contracts/visual';
|
|
3
|
-
import { useChatHost } from '../../host';
|
|
4
3
|
import { watchTheme } from './theme-watch';
|
|
4
|
+
import { useHostCodeMode } from '../../host-hooks';
|
|
5
5
|
|
|
6
6
|
/* The tokens of the app's theme where a frame stands; each answers '' for a token the theme lacks. */
|
|
7
7
|
export interface VisualTokens {
|
|
@@ -165,8 +165,7 @@ function readTheme(element: HTMLElement, mode: VisualAppearance): VisualTheme {
|
|
|
165
165
|
* accent or a font a person picks reaches every frame as well.
|
|
166
166
|
*/
|
|
167
167
|
export function useVisualTheme(ref: RefObject<HTMLElement | null>): VisualTheme | null {
|
|
168
|
-
const
|
|
169
|
-
const mode = host.code.useMode();
|
|
168
|
+
const mode = useHostCodeMode();
|
|
170
169
|
const [theme, setTheme] = useState<VisualTheme | null>(null);
|
|
171
170
|
useLayoutEffect(() => {
|
|
172
171
|
const element = ref.current;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
'use no memo';
|
|
2
|
+
/*
|
|
3
|
+
* The hooks a host hands the views, each called through a hook of its own here. To the React Compiler a
|
|
4
|
+
* hook read from a context may be another function on the next render, so it leaves a component that
|
|
5
|
+
* calls one as written. `ChatHostProvider` pins its host and a command look's hooks stay with its row's
|
|
6
|
+
* key, so they never change under a mounted view; only these wrappers go uncompiled for it.
|
|
7
|
+
*/
|
|
8
|
+
import type { ProviderPlatform } from '@adecore/agent-contracts';
|
|
9
|
+
import { useChatHost, type ChatHost, type CommandLook } from './host';
|
|
10
|
+
|
|
11
|
+
export function useHostCodeMode(): 'light' | 'dark' {
|
|
12
|
+
return useChatHost().code.useMode();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function useHostCodeThemes(): { light: string; dark: string } {
|
|
16
|
+
return useChatHost().code.useThemes();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function useHostAttachmentUrl(...args: Parameters<ChatHost['attachments']['useUrl']>): ReturnType<ChatHost['attachments']['useUrl']> {
|
|
20
|
+
return useChatHost().attachments.useUrl(...args);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function useHostTasks(...args: Parameters<ChatHost['tasks']['useTasks']>): ReturnType<ChatHost['tasks']['useTasks']> {
|
|
24
|
+
return useChatHost().tasks.useTasks(...args);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function useHostTask(...args: Parameters<ChatHost['tasks']['useTask']>): ReturnType<ChatHost['tasks']['useTask']> {
|
|
28
|
+
return useChatHost().tasks.useTask(...args);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function useHostExtraPrompts(...args: Parameters<ChatHost['prompts']['useExtra']>): ReturnType<ChatHost['prompts']['useExtra']> {
|
|
32
|
+
return useChatHost().prompts.useExtra(...args);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function useHostStreaming(): ReturnType<ChatHost['useStreaming']> {
|
|
36
|
+
return useChatHost().useStreaming();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function useHostSendDelivery(): ReturnType<ChatHost['useSendDelivery']> {
|
|
40
|
+
return useChatHost().useSendDelivery();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function useHostTimelineFind(...args: Parameters<ChatHost['useTimelineFind']>): ReturnType<ChatHost['useTimelineFind']> {
|
|
44
|
+
return useChatHost().useTimelineFind(...args);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function useHostReferableChats(): ReturnType<ChatHost['useReferableChats']> {
|
|
48
|
+
return useChatHost().useReferableChats();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function useHostLoginBlocked(...args: Parameters<ChatHost['useLoginBlocked']>): ReturnType<ChatHost['useLoginBlocked']> {
|
|
52
|
+
return useChatHost().useLoginBlocked(...args);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const noPlatform = (): ProviderPlatform | null => null;
|
|
56
|
+
|
|
57
|
+
/* Null where the host does not say, as it need not. */
|
|
58
|
+
export function useHostMachinePlatform(scopeId: string): ProviderPlatform | null {
|
|
59
|
+
const useMachinePlatform = useChatHost().useMachinePlatform ?? noPlatform;
|
|
60
|
+
return useMachinePlatform(scopeId);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function useHostProjectLook(...args: Parameters<ChatHost['useProjectLook']>): ReturnType<ChatHost['useProjectLook']> {
|
|
64
|
+
return useChatHost().useProjectLook(...args);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function useHostMachineLabel(...args: Parameters<ChatHost['useMachineLabel']>): ReturnType<ChatHost['useMachineLabel']> {
|
|
68
|
+
return useChatHost().useMachineLabel(...args);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function useHostChatPlace(...args: Parameters<ChatHost['useChatPlace']>): ReturnType<ChatHost['useChatPlace']> {
|
|
72
|
+
return useChatHost().useChatPlace(...args);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function useHostContextSources(...args: Parameters<ChatHost['useContextSources']>): ReturnType<ChatHost['useContextSources']> {
|
|
76
|
+
return useChatHost().useContextSources(...args);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function useHostHidesFolder(...args: Parameters<ChatHost['useHidesFolder']>): ReturnType<ChatHost['useHidesFolder']> {
|
|
80
|
+
return useChatHost().useHidesFolder(...args);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function useHostWelcome(...args: Parameters<ChatHost['useWelcome']>): ReturnType<ChatHost['useWelcome']> {
|
|
84
|
+
return useChatHost().useWelcome(...args);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function useHostResumeAtReset(...args: Parameters<ChatHost['useResumeAtReset']>): ReturnType<ChatHost['useResumeAtReset']> {
|
|
88
|
+
return useChatHost().useResumeAtReset(...args);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function useHostComposerPlaceholder(...args: Parameters<ChatHost['useComposerPlaceholder']>): ReturnType<ChatHost['useComposerPlaceholder']> {
|
|
92
|
+
return useChatHost().useComposerPlaceholder(...args);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function useHostThreadCards(...args: Parameters<ChatHost['useThreadCards']>): ReturnType<ChatHost['useThreadCards']> {
|
|
96
|
+
return useChatHost().useThreadCards(...args);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function useHostReplyAuthor(...args: Parameters<ChatHost['useReplyAuthor']>): ReturnType<ChatHost['useReplyAuthor']> {
|
|
100
|
+
return useChatHost().useReplyAuthor(...args);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function useHostMapSource(maps: NonNullable<ChatHost['maps']>, scopeId: string): ReturnType<NonNullable<ChatHost['maps']>['useSource']> {
|
|
104
|
+
return maps.useSource(scopeId);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function useCommandNames(
|
|
108
|
+
look: Required<Pick<CommandLook, 'useNames'>>,
|
|
109
|
+
scopeId: string,
|
|
110
|
+
chatId: string
|
|
111
|
+
): ReturnType<NonNullable<CommandLook['useNames']>> {
|
|
112
|
+
return look.useNames(scopeId, chatId);
|
|
113
|
+
}
|
package/src/lazy.tsx
CHANGED
|
@@ -58,6 +58,8 @@ export function lazyNamed<Module extends Record<Name, ComponentType<any>>, Name
|
|
|
58
58
|
}
|
|
59
59
|
});
|
|
60
60
|
const LazyNamed = (props: ComponentProps<Module[Name]>) => {
|
|
61
|
+
// `loaded` fills in place; compiled, the element drawn before the module landed would stay.
|
|
62
|
+
'use no memo';
|
|
61
63
|
const Component: ComponentType<any> = loaded.current ?? Lazy;
|
|
62
64
|
return <Component {...props} />;
|
|
63
65
|
};
|