@adecore/agents-react 0.0.1 → 0.17.0-beta.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/LICENSE +110 -0
- package/README.md +53 -0
- package/dist/agents/AccountDot.d.ts +4 -0
- package/dist/agents/AccountDot.js +8 -0
- package/dist/agents/AgentIcon.d.ts +6 -0
- package/dist/agents/AgentIcon.js +20 -0
- package/dist/agents/ModelOptionControl.d.ts +15 -0
- package/dist/agents/ModelOptionControl.js +33 -0
- package/dist/agents/ProviderLogo.d.ts +8 -0
- package/dist/agents/ProviderLogo.js +8 -0
- package/dist/agents/account-limits.d.ts +7 -0
- package/dist/agents/account-limits.js +40 -0
- package/dist/agents/accounts.d.ts +22 -0
- package/dist/agents/accounts.js +113 -0
- package/dist/agents/model-name.d.ts +12 -0
- package/dist/agents/model-name.js +56 -0
- package/dist/agents/model-options.d.ts +5 -0
- package/dist/agents/model-options.js +15 -0
- package/dist/agents/provider-paths.d.ts +2 -0
- package/dist/agents/provider-paths.js +8 -0
- package/dist/agents/status-look.d.ts +13 -0
- package/dist/agents/status-look.js +24 -0
- package/dist/chat/account-choice.d.ts +11 -0
- package/dist/chat/account-choice.js +30 -0
- package/dist/chat/actions.d.ts +6 -0
- package/dist/chat/actions.js +68 -0
- package/dist/chat/activity.d.ts +5 -0
- package/dist/chat/activity.js +6 -0
- package/dist/chat/attachments.d.ts +23 -0
- package/dist/chat/attachments.js +86 -0
- package/dist/chat/bookmarks.d.ts +14 -0
- package/dist/chat/bookmarks.js +73 -0
- package/dist/chat/chat-client.d.ts +55 -0
- package/dist/chat/chat-client.js +279 -0
- package/dist/chat/chat-references.d.ts +5 -0
- package/dist/chat/chat-references.js +5 -0
- package/dist/chat/drafts.d.ts +29 -0
- package/dist/chat/drafts.js +116 -0
- package/dist/chat/forks.d.ts +2 -0
- package/dist/chat/forks.js +28 -0
- package/dist/chat/guards.d.ts +12 -0
- package/dist/chat/guards.js +69 -0
- package/dist/chat/logic/ansi.d.ts +13 -0
- package/dist/chat/logic/ansi.js +185 -0
- package/dist/chat/logic/answers.d.ts +1 -0
- package/dist/chat/logic/answers.js +8 -0
- package/dist/chat/logic/bookmarks.d.ts +5 -0
- package/dist/chat/logic/bookmarks.js +33 -0
- package/dist/chat/logic/context-usage.d.ts +12 -0
- package/dist/chat/logic/context-usage.js +21 -0
- package/dist/chat/logic/fork.d.ts +45 -0
- package/dist/chat/logic/fork.js +148 -0
- package/dist/chat/logic/handback.d.ts +2 -0
- package/dist/chat/logic/handback.js +8 -0
- package/dist/chat/logic/json.d.ts +1 -0
- package/dist/chat/logic/json.js +4 -0
- package/dist/chat/logic/limit.d.ts +7 -0
- package/dist/chat/logic/limit.js +34 -0
- package/dist/chat/logic/resume-compaction.d.ts +14 -0
- package/dist/chat/logic/resume-compaction.js +47 -0
- package/dist/chat/logic/scrubber.d.ts +50 -0
- package/dist/chat/logic/scrubber.js +220 -0
- package/dist/chat/logic/thread-cards.d.ts +3 -0
- package/dist/chat/logic/thread-cards.js +59 -0
- package/dist/chat/logic/timeline-copy.d.ts +4 -0
- package/dist/chat/logic/timeline-copy.js +59 -0
- package/dist/chat/logic/timeline-target.d.ts +12 -0
- package/dist/chat/logic/timeline-target.js +34 -0
- package/dist/chat/logic/timeline.d.ts +115 -0
- package/dist/chat/logic/timeline.js +343 -0
- package/dist/chat/logic/tool-catalog.d.ts +10 -0
- package/dist/chat/logic/tool-catalog.js +44 -0
- package/dist/chat/logic/tools.d.ts +15 -0
- package/dist/chat/logic/tools.js +82 -0
- package/dist/chat/logic/welcome.d.ts +2 -0
- package/dist/chat/logic/welcome.js +10 -0
- package/dist/chat/logic/workflow.d.ts +14 -0
- package/dist/chat/logic/workflow.js +47 -0
- package/dist/chat/mentions.d.ts +65 -0
- package/dist/chat/mentions.js +184 -0
- package/dist/chat/persisted-json.d.ts +5 -0
- package/dist/chat/persisted-json.js +58 -0
- package/dist/chat/preferences.d.ts +27 -0
- package/dist/chat/preferences.js +139 -0
- package/dist/chat/quote.d.ts +2 -0
- package/dist/chat/quote.js +25 -0
- package/dist/chat/recent-messages.d.ts +17 -0
- package/dist/chat/recent-messages.js +36 -0
- package/dist/chat/resume-compaction-dismissals.d.ts +3 -0
- package/dist/chat/resume-compaction-dismissals.js +14 -0
- package/dist/chat/runtime-modes.d.ts +4 -0
- package/dist/chat/runtime-modes.js +15 -0
- package/dist/chat/stash.d.ts +24 -0
- package/dist/chat/stash.js +91 -0
- package/dist/chat/subagent-conversation.d.ts +41 -0
- package/dist/chat/subagent-conversation.js +167 -0
- package/dist/chat/subagent-list.d.ts +19 -0
- package/dist/chat/subagent-list.js +106 -0
- package/dist/chat/subagent-support.d.ts +6 -0
- package/dist/chat/subagent-support.js +14 -0
- package/dist/chat/subagent-view.d.ts +35 -0
- package/dist/chat/subagent-view.js +96 -0
- package/dist/chat/thumbnails.d.ts +10 -0
- package/dist/chat/thumbnails.js +89 -0
- package/dist/chat/timeline-flash.d.ts +12 -0
- package/dist/chat/timeline-flash.js +16 -0
- package/dist/chat/timeline-scroll.d.ts +27 -0
- package/dist/chat/timeline-scroll.js +152 -0
- package/dist/chat/ui/AccountPill.d.ts +3 -0
- package/dist/chat/ui/AccountPill.js +23 -0
- package/dist/chat/ui/AnsiOutput.d.ts +5 -0
- package/dist/chat/ui/AnsiOutput.js +9 -0
- package/dist/chat/ui/BookmarkMarker.d.ts +8 -0
- package/dist/chat/ui/BookmarkMarker.js +57 -0
- package/dist/chat/ui/BookmarkSubmenu.d.ts +3 -0
- package/dist/chat/ui/BookmarkSubmenu.js +33 -0
- package/dist/chat/ui/ChatActivity.d.ts +7 -0
- package/dist/chat/ui/ChatActivity.js +84 -0
- package/dist/chat/ui/ChatReferenceChip.d.ts +4 -0
- package/dist/chat/ui/ChatReferenceChip.js +16 -0
- package/dist/chat/ui/CodeBlock.d.ts +4 -0
- package/dist/chat/ui/CodeBlock.js +132 -0
- package/dist/chat/ui/Composer.d.ts +15 -0
- package/dist/chat/ui/Composer.js +856 -0
- package/dist/chat/ui/ComposerInput.d.ts +29 -0
- package/dist/chat/ui/ComposerInput.js +127 -0
- package/dist/chat/ui/DiffPool.d.ts +5 -0
- package/dist/chat/ui/DiffPool.js +26 -0
- package/dist/chat/ui/EditDiff.d.ts +4 -0
- package/dist/chat/ui/EditDiff.js +21 -0
- package/dist/chat/ui/FadingWords.d.ts +3 -0
- package/dist/chat/ui/FadingWords.js +5 -0
- package/dist/chat/ui/ImageView.d.ts +6 -0
- package/dist/chat/ui/ImageView.js +81 -0
- package/dist/chat/ui/LimitState.d.ts +8 -0
- package/dist/chat/ui/LimitState.js +112 -0
- package/dist/chat/ui/Markdown.d.ts +18 -0
- package/dist/chat/ui/Markdown.js +159 -0
- package/dist/chat/ui/MessageActions.d.ts +9 -0
- package/dist/chat/ui/MessageActions.js +53 -0
- package/dist/chat/ui/Pickers.d.ts +21 -0
- package/dist/chat/ui/Pickers.js +111 -0
- package/dist/chat/ui/PromptComposer.d.ts +13 -0
- package/dist/chat/ui/PromptComposer.js +56 -0
- package/dist/chat/ui/QuoteButton.d.ts +7 -0
- package/dist/chat/ui/QuoteButton.js +74 -0
- package/dist/chat/ui/ResumeCompactionDock.d.ts +5 -0
- package/dist/chat/ui/ResumeCompactionDock.js +14 -0
- package/dist/chat/ui/RunSettings.d.ts +28 -0
- package/dist/chat/ui/RunSettings.js +153 -0
- package/dist/chat/ui/Scrubber.d.ts +17 -0
- package/dist/chat/ui/Scrubber.js +118 -0
- package/dist/chat/ui/SubagentControls.d.ts +11 -0
- package/dist/chat/ui/SubagentControls.js +36 -0
- package/dist/chat/ui/SubagentInfo.d.ts +4 -0
- package/dist/chat/ui/SubagentInfo.js +34 -0
- package/dist/chat/ui/SubagentStopButton.d.ts +7 -0
- package/dist/chat/ui/SubagentStopButton.js +34 -0
- package/dist/chat/ui/SubagentTimeline.d.ts +4 -0
- package/dist/chat/ui/SubagentTimeline.js +107 -0
- package/dist/chat/ui/Timeline.d.ts +6 -0
- package/dist/chat/ui/Timeline.js +424 -0
- package/dist/chat/ui/TimelineMenu.d.ts +12 -0
- package/dist/chat/ui/TimelineMenu.js +54 -0
- package/dist/chat/ui/UnifiedDiff.d.ts +11 -0
- package/dist/chat/ui/UnifiedDiff.js +66 -0
- package/dist/chat/ui/UploadThumb.d.ts +4 -0
- package/dist/chat/ui/UploadThumb.js +11 -0
- package/dist/chat/ui/Welcome.d.ts +4 -0
- package/dist/chat/ui/Welcome.js +16 -0
- package/dist/chat/ui/chips.d.ts +4 -0
- package/dist/chat/ui/chips.js +11 -0
- package/dist/chat/ui/code-lines.d.ts +18 -0
- package/dist/chat/ui/code-lines.js +46 -0
- package/dist/chat/ui/code-streaming.d.ts +1 -0
- package/dist/chat/ui/code-streaming.js +3 -0
- package/dist/chat/ui/code-theme.d.ts +3 -0
- package/dist/chat/ui/code-theme.js +12 -0
- package/dist/chat/ui/composer/chips.d.ts +6 -0
- package/dist/chat/ui/composer/chips.js +31 -0
- package/dist/chat/ui/composer/editor.d.ts +11 -0
- package/dist/chat/ui/composer/editor.js +98 -0
- package/dist/chat/ui/composer/insert.d.ts +2 -0
- package/dist/chat/ui/composer/insert.js +19 -0
- package/dist/chat/ui/composer/keys.d.ts +30 -0
- package/dist/chat/ui/composer/keys.js +100 -0
- package/dist/chat/ui/diff-theme.d.ts +2 -0
- package/dist/chat/ui/diff-theme.js +20 -0
- package/dist/chat/ui/file-links.d.ts +5 -0
- package/dist/chat/ui/file-links.js +20 -0
- package/dist/chat/ui/find-reveal.d.ts +7 -0
- package/dist/chat/ui/find-reveal.js +13 -0
- package/dist/chat/ui/full-diff.d.ts +6 -0
- package/dist/chat/ui/full-diff.js +19 -0
- package/dist/chat/ui/icons.d.ts +4 -0
- package/dist/chat/ui/icons.js +20 -0
- package/dist/chat/ui/markdown-blocks.d.ts +6 -0
- package/dist/chat/ui/markdown-blocks.js +103 -0
- package/dist/chat/ui/quote-selection.d.ts +3 -0
- package/dist/chat/ui/quote-selection.js +46 -0
- package/dist/chat/ui/rehype-chips.d.ts +23 -0
- package/dist/chat/ui/rehype-chips.js +32 -0
- package/dist/chat/ui/rehype-fade.d.ts +23 -0
- package/dist/chat/ui/rehype-fade.js +36 -0
- package/dist/chat/ui/remark-html-as-text.d.ts +8 -0
- package/dist/chat/ui/remark-html-as-text.js +26 -0
- package/dist/chat/ui/reply-context.d.ts +5 -0
- package/dist/chat/ui/reply-context.js +2 -0
- package/dist/chat/ui/reveal.d.ts +13 -0
- package/dist/chat/ui/reveal.js +114 -0
- package/dist/chat/ui/rows/ForksRow.d.ts +4 -0
- package/dist/chat/ui/rows/ForksRow.js +38 -0
- package/dist/chat/ui/rows/MessageRows.d.ts +40 -0
- package/dist/chat/ui/rows/MessageRows.js +204 -0
- package/dist/chat/ui/rows/Rows.d.ts +12 -0
- package/dist/chat/ui/rows/Rows.js +61 -0
- package/dist/chat/ui/rows/SubagentRow.d.ts +17 -0
- package/dist/chat/ui/rows/SubagentRow.js +101 -0
- package/dist/chat/ui/rows/TaskRow.d.ts +8 -0
- package/dist/chat/ui/rows/TaskRow.js +63 -0
- package/dist/chat/ui/rows/WorkRows.d.ts +47 -0
- package/dist/chat/ui/rows/WorkRows.js +168 -0
- package/dist/chat/ui/rows/WorkflowRow.d.ts +8 -0
- package/dist/chat/ui/rows/WorkflowRow.js +48 -0
- package/dist/chat/ui/rows/row-rhythm.d.ts +6 -0
- package/dist/chat/ui/rows/row-rhythm.js +34 -0
- package/dist/chat/ui/useToggleSet.d.ts +6 -0
- package/dist/chat/ui/useToggleSet.js +25 -0
- package/dist/host.d.ts +195 -0
- package/dist/host.js +55 -0
- package/dist/lazy.d.ts +6 -0
- package/dist/lazy.js +57 -0
- package/dist/locales/en/agent-chat.json +446 -0
- package/dist/locales/en/agent-prompts.json +42 -0
- package/dist/locales/en/agent-providers.json +131 -0
- package/dist/locales/en/agent-usage.json +131 -0
- package/dist/locales/nl/agent-chat.json +446 -0
- package/dist/locales/nl/agent-prompts.json +42 -0
- package/dist/locales/nl/agent-providers.json +131 -0
- package/dist/locales/nl/agent-usage.json +131 -0
- package/dist/locales.d.ts +5 -0
- package/dist/locales.js +20 -0
- package/dist/mounted-registry.d.ts +7 -0
- package/dist/mounted-registry.js +39 -0
- package/dist/port-transport.d.ts +6 -0
- package/dist/port-transport.js +129 -0
- package/dist/prompts/logic/focus.d.ts +2 -0
- package/dist/prompts/logic/focus.js +23 -0
- package/dist/prompts/logic/keys.d.ts +42 -0
- package/dist/prompts/logic/keys.js +94 -0
- package/dist/prompts/logic/prompts.d.ts +34 -0
- package/dist/prompts/logic/prompts.fixtures.d.ts +5 -0
- package/dist/prompts/logic/prompts.fixtures.js +79 -0
- package/dist/prompts/logic/prompts.js +32 -0
- package/dist/prompts/logic/subjects.d.ts +50 -0
- package/dist/prompts/logic/subjects.js +63 -0
- package/dist/prompts/logic/useFocusAfterAnswer.d.ts +6 -0
- package/dist/prompts/logic/useFocusAfterAnswer.js +28 -0
- package/dist/prompts/logic/usePromptSession.d.ts +24 -0
- package/dist/prompts/logic/usePromptSession.js +87 -0
- package/dist/prompts/ui/ApprovalBody.d.ts +13 -0
- package/dist/prompts/ui/ApprovalBody.js +34 -0
- package/dist/prompts/ui/PromptActions.d.ts +27 -0
- package/dist/prompts/ui/PromptActions.js +18 -0
- package/dist/prompts/ui/PromptCard.d.ts +16 -0
- package/dist/prompts/ui/PromptCard.js +50 -0
- package/dist/prompts/ui/PromptView.d.ts +2 -0
- package/dist/prompts/ui/PromptView.js +47 -0
- package/dist/prompts/ui/QuestionBody.d.ts +9 -0
- package/dist/prompts/ui/QuestionBody.js +87 -0
- package/dist/providers/AccountColors.d.ts +5 -0
- package/dist/providers/AccountColors.js +8 -0
- package/dist/providers/AccountDetail.d.ts +12 -0
- package/dist/providers/AccountDetail.js +69 -0
- package/dist/providers/AccountVariables.d.ts +8 -0
- package/dist/providers/AccountVariables.js +43 -0
- package/dist/providers/AddAccountForm.d.ts +10 -0
- package/dist/providers/AddAccountForm.js +54 -0
- package/dist/providers/CliDetail.d.ts +12 -0
- package/dist/providers/CliDetail.js +54 -0
- package/dist/providers/ProvidersPane.d.ts +9 -0
- package/dist/providers/ProvidersPane.js +86 -0
- package/dist/providers/account-actions.d.ts +7 -0
- package/dist/providers/account-actions.js +57 -0
- package/dist/providers/parts.d.ts +9 -0
- package/dist/providers/parts.js +18 -0
- package/dist/providers/provider-abilities.d.ts +2 -0
- package/dist/providers/provider-abilities.js +7 -0
- package/dist/providers/variables.d.ts +13 -0
- package/dist/providers/variables.js +63 -0
- package/dist/scope.d.ts +11 -0
- package/dist/scope.js +10 -0
- package/dist/settings/sections.d.ts +13 -0
- package/dist/settings/sections.js +32 -0
- package/dist/state/chats.d.ts +44 -0
- package/dist/state/chats.js +199 -0
- package/dist/state/provider-accounts.d.ts +17 -0
- package/dist/state/provider-accounts.js +67 -0
- package/dist/state/providers.d.ts +17 -0
- package/dist/state/providers.js +33 -0
- package/dist/state/usage.d.ts +44 -0
- package/dist/state/usage.js +121 -0
- package/dist/storage.d.ts +20 -0
- package/dist/storage.js +89 -0
- package/dist/theme.css +196 -0
- package/dist/transport.d.ts +24 -0
- package/dist/transport.js +18 -0
- package/dist/ui/PlainTextarea.d.ts +2 -0
- package/dist/ui/PlainTextarea.js +5 -0
- package/dist/usage/LimitsList.d.ts +18 -0
- package/dist/usage/LimitsList.js +73 -0
- package/dist/usage/UsageBreakdown.d.ts +9 -0
- package/dist/usage/UsageBreakdown.js +67 -0
- package/dist/usage/UsageChart.d.ts +10 -0
- package/dist/usage/UsageChart.js +47 -0
- package/dist/usage/UsageDialog.d.ts +6 -0
- package/dist/usage/UsageDialog.js +12 -0
- package/dist/usage/UsageLimits.d.ts +1 -0
- package/dist/usage/UsageLimits.js +57 -0
- package/dist/usage/UsageLimitsCard.d.ts +4 -0
- package/dist/usage/UsageLimitsCard.js +26 -0
- package/dist/usage/UsagePage.d.ts +7 -0
- package/dist/usage/UsagePage.js +154 -0
- package/dist/usage/UsagePane.d.ts +3 -0
- package/dist/usage/UsagePane.js +21 -0
- package/dist/usage/UsageSummary.d.ts +12 -0
- package/dist/usage/UsageSummary.js +15 -0
- package/dist/usage/UsageTiles.d.ts +7 -0
- package/dist/usage/UsageTiles.js +19 -0
- package/dist/usage/format.d.ts +13 -0
- package/dist/usage/format.js +55 -0
- package/dist/usage/limit-groups.d.ts +22 -0
- package/dist/usage/limit-groups.js +86 -0
- package/dist/usage/limits.d.ts +4 -0
- package/dist/usage/limits.js +58 -0
- package/dist/usage/money.d.ts +1 -0
- package/dist/usage/money.js +13 -0
- package/dist/usage/summary.d.ts +34 -0
- package/dist/usage/summary.js +94 -0
- package/package.json +895 -3
- package/src/agents/AccountDot.tsx +14 -0
- package/src/agents/AgentIcon.tsx +26 -0
- package/src/agents/ModelOptionControl.tsx +68 -0
- package/src/agents/ProviderLogo.tsx +20 -0
- package/src/agents/account-limits.ts +61 -0
- package/src/agents/accounts.ts +137 -0
- package/src/agents/model-name.ts +70 -0
- package/src/agents/model-options.ts +21 -0
- package/src/agents/provider-paths.ts +10 -0
- package/src/agents/status-look.ts +43 -0
- package/src/chat/account-choice.ts +44 -0
- package/src/chat/actions.ts +72 -0
- package/src/chat/activity.ts +8 -0
- package/src/chat/attachments.ts +118 -0
- package/src/chat/bookmarks.ts +87 -0
- package/src/chat/chat-client.ts +345 -0
- package/src/chat/chat-references.ts +11 -0
- package/src/chat/drafts.ts +165 -0
- package/src/chat/forks.ts +33 -0
- package/src/chat/guards.ts +84 -0
- package/src/chat/logic/ansi.ts +206 -0
- package/src/chat/logic/answers.ts +8 -0
- package/src/chat/logic/bookmarks.ts +42 -0
- package/src/chat/logic/context-usage.ts +36 -0
- package/src/chat/logic/fork.ts +200 -0
- package/src/chat/logic/handback.ts +10 -0
- package/src/chat/logic/json.ts +4 -0
- package/src/chat/logic/limit.ts +46 -0
- package/src/chat/logic/resume-compaction.ts +71 -0
- package/src/chat/logic/scrubber.ts +289 -0
- package/src/chat/logic/thread-cards.ts +64 -0
- package/src/chat/logic/timeline-copy.ts +65 -0
- package/src/chat/logic/timeline-target.ts +52 -0
- package/src/chat/logic/timeline.ts +419 -0
- package/src/chat/logic/tool-catalog.ts +62 -0
- package/src/chat/logic/tools.ts +102 -0
- package/src/chat/logic/welcome.ts +13 -0
- package/src/chat/logic/workflow.ts +66 -0
- package/src/chat/mentions.ts +232 -0
- package/src/chat/persisted-json.ts +67 -0
- package/src/chat/preferences.ts +179 -0
- package/src/chat/quote.ts +26 -0
- package/src/chat/recent-messages.ts +59 -0
- package/src/chat/resume-compaction-dismissals.ts +17 -0
- package/src/chat/runtime-modes.ts +18 -0
- package/src/chat/stash.ts +122 -0
- package/src/chat/subagent-conversation.ts +203 -0
- package/src/chat/subagent-list.ts +141 -0
- package/src/chat/subagent-support.ts +21 -0
- package/src/chat/subagent-view.ts +137 -0
- package/src/chat/thumbnails.ts +108 -0
- package/src/chat/timeline-flash.ts +33 -0
- package/src/chat/timeline-scroll.ts +199 -0
- package/src/chat/ui/AccountPill.tsx +31 -0
- package/src/chat/ui/AnsiOutput.tsx +18 -0
- package/src/chat/ui/BookmarkMarker.tsx +108 -0
- package/src/chat/ui/BookmarkSubmenu.tsx +53 -0
- package/src/chat/ui/ChatActivity.tsx +198 -0
- package/src/chat/ui/ChatReferenceChip.tsx +28 -0
- package/src/chat/ui/CodeBlock.tsx +175 -0
- package/src/chat/ui/Composer.tsx +1326 -0
- package/src/chat/ui/ComposerInput.tsx +187 -0
- package/src/chat/ui/DiffPool.tsx +36 -0
- package/src/chat/ui/EditDiff.tsx +30 -0
- package/src/chat/ui/FadingWords.tsx +18 -0
- package/src/chat/ui/ImageView.tsx +159 -0
- package/src/chat/ui/LimitState.tsx +165 -0
- package/src/chat/ui/Markdown.tsx +258 -0
- package/src/chat/ui/MessageActions.tsx +88 -0
- package/src/chat/ui/Pickers.tsx +272 -0
- package/src/chat/ui/PromptComposer.tsx +119 -0
- package/src/chat/ui/QuoteButton.tsx +103 -0
- package/src/chat/ui/ResumeCompactionDock.tsx +28 -0
- package/src/chat/ui/RunSettings.tsx +546 -0
- package/src/chat/ui/Scrubber.tsx +265 -0
- package/src/chat/ui/SubagentControls.tsx +66 -0
- package/src/chat/ui/SubagentInfo.tsx +67 -0
- package/src/chat/ui/SubagentStopButton.tsx +45 -0
- package/src/chat/ui/SubagentTimeline.tsx +170 -0
- package/src/chat/ui/Timeline.tsx +628 -0
- package/src/chat/ui/TimelineMenu.tsx +124 -0
- package/src/chat/ui/UnifiedDiff.tsx +99 -0
- package/src/chat/ui/UploadThumb.tsx +13 -0
- package/src/chat/ui/Welcome.tsx +22 -0
- package/src/chat/ui/chips.ts +15 -0
- package/src/chat/ui/code-lines.ts +60 -0
- package/src/chat/ui/code-streaming.ts +4 -0
- package/src/chat/ui/code-theme.ts +15 -0
- package/src/chat/ui/composer/chips.ts +43 -0
- package/src/chat/ui/composer/editor.ts +118 -0
- package/src/chat/ui/composer/insert.ts +22 -0
- package/src/chat/ui/composer/keys.ts +144 -0
- package/src/chat/ui/diff-theme.ts +23 -0
- package/src/chat/ui/file-links.ts +24 -0
- package/src/chat/ui/find-reveal.ts +23 -0
- package/src/chat/ui/full-diff.ts +25 -0
- package/src/chat/ui/icons.tsx +24 -0
- package/src/chat/ui/markdown-blocks.ts +123 -0
- package/src/chat/ui/quote-selection.ts +53 -0
- package/src/chat/ui/rehype-chips.ts +62 -0
- package/src/chat/ui/rehype-fade.ts +64 -0
- package/src/chat/ui/remark-html-as-text.ts +36 -0
- package/src/chat/ui/reply-context.ts +4 -0
- package/src/chat/ui/reveal.ts +135 -0
- package/src/chat/ui/rows/ForksRow.tsx +79 -0
- package/src/chat/ui/rows/MessageRows.tsx +415 -0
- package/src/chat/ui/rows/Rows.tsx +81 -0
- package/src/chat/ui/rows/SubagentRow.tsx +209 -0
- package/src/chat/ui/rows/TaskRow.tsx +91 -0
- package/src/chat/ui/rows/WorkRows.tsx +445 -0
- package/src/chat/ui/rows/WorkflowRow.tsx +120 -0
- package/src/chat/ui/rows/row-rhythm.ts +37 -0
- package/src/chat/ui/useToggleSet.ts +39 -0
- package/src/host.ts +324 -0
- package/src/lazy.tsx +64 -0
- package/src/locales/en/agent-chat.json +446 -0
- package/src/locales/en/agent-prompts.json +42 -0
- package/src/locales/en/agent-providers.json +131 -0
- package/src/locales/en/agent-usage.json +131 -0
- package/src/locales/nl/agent-chat.json +446 -0
- package/src/locales/nl/agent-prompts.json +42 -0
- package/src/locales/nl/agent-providers.json +131 -0
- package/src/locales/nl/agent-usage.json +131 -0
- package/src/locales.ts +33 -0
- package/src/mounted-registry.ts +45 -0
- package/src/port-transport.ts +146 -0
- package/src/prompts/logic/focus.ts +25 -0
- package/src/prompts/logic/keys.ts +116 -0
- package/src/prompts/logic/prompts.fixtures.ts +84 -0
- package/src/prompts/logic/prompts.ts +58 -0
- package/src/prompts/logic/subjects.ts +122 -0
- package/src/prompts/logic/useFocusAfterAnswer.ts +38 -0
- package/src/prompts/logic/usePromptSession.ts +114 -0
- package/src/prompts/ui/ApprovalBody.tsx +109 -0
- package/src/prompts/ui/PromptActions.tsx +109 -0
- package/src/prompts/ui/PromptCard.tsx +101 -0
- package/src/prompts/ui/PromptView.tsx +111 -0
- package/src/prompts/ui/QuestionBody.tsx +174 -0
- package/src/providers/AccountColors.tsx +8 -0
- package/src/providers/AccountDetail.tsx +209 -0
- package/src/providers/AccountVariables.tsx +126 -0
- package/src/providers/AddAccountForm.tsx +121 -0
- package/src/providers/CliDetail.tsx +157 -0
- package/src/providers/ProvidersPane.tsx +236 -0
- package/src/providers/account-actions.ts +67 -0
- package/src/providers/parts.tsx +25 -0
- package/src/providers/provider-abilities.ts +9 -0
- package/src/providers/variables.ts +87 -0
- package/src/scope.ts +30 -0
- package/src/settings/sections.ts +47 -0
- package/src/state/chats.ts +279 -0
- package/src/state/provider-accounts.ts +87 -0
- package/src/state/providers.ts +50 -0
- package/src/state/usage.ts +196 -0
- package/src/storage.ts +113 -0
- package/src/theme.css +196 -0
- package/src/transport.ts +50 -0
- package/src/ui/PlainTextarea.tsx +6 -0
- package/src/usage/LimitsList.tsx +232 -0
- package/src/usage/UsageBreakdown.tsx +210 -0
- package/src/usage/UsageChart.tsx +113 -0
- package/src/usage/UsageDialog.tsx +20 -0
- package/src/usage/UsageLimits.tsx +145 -0
- package/src/usage/UsageLimitsCard.tsx +36 -0
- package/src/usage/UsagePage.tsx +276 -0
- package/src/usage/UsagePane.tsx +52 -0
- package/src/usage/UsageSummary.tsx +50 -0
- package/src/usage/UsageTiles.tsx +34 -0
- package/src/usage/format.ts +71 -0
- package/src/usage/limit-groups.ts +119 -0
- package/src/usage/limits.ts +71 -0
- package/src/usage/money.ts +14 -0
- package/src/usage/summary.ts +137 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { stripAnsi } from './ansi.js';
|
|
2
|
+
/*
|
|
3
|
+
* What a row of the thread puts on the clipboard. An answer is markdown on the wire and rendered
|
|
4
|
+
* text on the screen, so copying it as text has to undo the marks the renderer swallowed; the
|
|
5
|
+
* source itself stays available as "Copy as markdown".
|
|
6
|
+
*/
|
|
7
|
+
/*
|
|
8
|
+
* The marks that only exist to be rendered come off, what they marked stays. `_` is left alone on
|
|
9
|
+
* purpose: it is a letter in half the identifiers an agent writes, and no italic is worth mangling
|
|
10
|
+
* `file_path`.
|
|
11
|
+
*/
|
|
12
|
+
export function stripMarkdown(text) {
|
|
13
|
+
return text
|
|
14
|
+
.replace(/^ *```[^\n]*\n?/gm, '')
|
|
15
|
+
.replace(/^ *(#{1,6}) +/gm, '')
|
|
16
|
+
.replace(/^ *> ?/gm, '')
|
|
17
|
+
.replace(/!\[([^\]]*)\]\([^)]*\)/g, '$1')
|
|
18
|
+
.replace(/\[([^\]]*)\]\([^)]*\)/g, '$1')
|
|
19
|
+
.replace(/(\*\*|__)(?=\S)([\s\S]*?\S)\1/g, '$2')
|
|
20
|
+
.replace(/\*(?=\S)([^*\n]*\S)\*/g, '$1')
|
|
21
|
+
.replace(/`+([^`]+)`+/g, '$1')
|
|
22
|
+
.trim();
|
|
23
|
+
}
|
|
24
|
+
/* What a tool call has to show for itself: what it answered, or what it has answered so far. */
|
|
25
|
+
function outputOf(tool) {
|
|
26
|
+
const output = tool.output ?? tool.progress?.output ?? null;
|
|
27
|
+
return output === null ? null : stripAnsi(output);
|
|
28
|
+
}
|
|
29
|
+
/* The whole item under the pointer as plain text, or null for a row that carries no message. */
|
|
30
|
+
export function messageTextOf(row) {
|
|
31
|
+
switch (row.kind) {
|
|
32
|
+
case 'user':
|
|
33
|
+
return row.item.text || null;
|
|
34
|
+
case 'assistant':
|
|
35
|
+
return stripMarkdown(row.item.text) || null;
|
|
36
|
+
case 'report':
|
|
37
|
+
return stripMarkdown(row.text) || null;
|
|
38
|
+
case 'thinking':
|
|
39
|
+
return row.item.text || null;
|
|
40
|
+
case 'work':
|
|
41
|
+
case 'work-live':
|
|
42
|
+
case 'workflow':
|
|
43
|
+
return outputOf(row.tool);
|
|
44
|
+
case 'work-group': {
|
|
45
|
+
const outputs = row.tools.map(outputOf).filter((output) => output !== null);
|
|
46
|
+
return outputs.length > 0 ? outputs.join('\n\n') : null;
|
|
47
|
+
}
|
|
48
|
+
case 'subagent':
|
|
49
|
+
return row.item.result ?? row.item.summary ?? null;
|
|
50
|
+
case 'note':
|
|
51
|
+
return row.text;
|
|
52
|
+
default:
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/* The markdown an answer was written in; every other row has none to copy. */
|
|
57
|
+
export function markdownOf(row) {
|
|
58
|
+
return row.kind === 'assistant' ? row.item.text || null : row.kind === 'report' ? row.text || null : null;
|
|
59
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ChatItem } from '@adecore/agent-contracts';
|
|
2
|
+
import type { TimelineRow } from './timeline.js';
|
|
3
|
+
export interface TimelineTarget {
|
|
4
|
+
selection: string;
|
|
5
|
+
row: TimelineRow | null;
|
|
6
|
+
code: string | null;
|
|
7
|
+
path: string | null;
|
|
8
|
+
line: number | null;
|
|
9
|
+
}
|
|
10
|
+
export declare const EMPTY_TARGET: TimelineTarget;
|
|
11
|
+
export declare function withCurrentText(rows: TimelineRow[], items: Record<string, ChatItem> | undefined): TimelineRow[];
|
|
12
|
+
export declare function readTimelineTarget(element: HTMLElement, scroller: HTMLElement | null, rows: TimelineRow[]): TimelineTarget;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { selectionWithin } from '@adecore/ui';
|
|
2
|
+
export const EMPTY_TARGET = { selection: '', row: null, code: null, path: null, line: null };
|
|
3
|
+
/*
|
|
4
|
+
* The rows with the text a reply or a thought holds now. Rows are derived from the structure of a
|
|
5
|
+
* thread, which a delta leaves alone, so a row still carries the text it was derived with.
|
|
6
|
+
*/
|
|
7
|
+
export function withCurrentText(rows, items) {
|
|
8
|
+
if (!items) {
|
|
9
|
+
return rows;
|
|
10
|
+
}
|
|
11
|
+
return rows.map((row) => {
|
|
12
|
+
const item = items[row.id];
|
|
13
|
+
if (row.kind === 'assistant' && item?.kind === 'assistant') {
|
|
14
|
+
return { ...row, item };
|
|
15
|
+
}
|
|
16
|
+
if (row.kind === 'thinking' && item?.kind === 'thinking') {
|
|
17
|
+
return { ...row, item };
|
|
18
|
+
}
|
|
19
|
+
return row;
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
/* The row a click landed in is the one whose id it sits under; the rest comes from the same walk up. */
|
|
23
|
+
export function readTimelineTarget(element, scroller, rows) {
|
|
24
|
+
const id = element.closest('[data-item-id]')?.dataset.itemId;
|
|
25
|
+
const file = element.closest('[data-file-path]');
|
|
26
|
+
const line = Number(file?.dataset.fileLine);
|
|
27
|
+
return {
|
|
28
|
+
selection: selectionWithin(scroller),
|
|
29
|
+
row: rows.find((row) => row.id === id) ?? null,
|
|
30
|
+
code: element.closest('pre')?.textContent ?? null,
|
|
31
|
+
path: file?.dataset.filePath ?? null,
|
|
32
|
+
line: Number.isFinite(line) && line > 0 ? line : null
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import type { ChatApprovalItem, ChatAssistantItem, ChatCheckpointDiff, ChatItem, ChatQuestionItem, ChatSubagentItem, ChatThinkingItem, ChatToolItem, ChatTurnItem, ChatUserItem, ChatWorkflow } from '@adecore/agent-contracts';
|
|
2
|
+
import type { ThreadCard } from '../../host.js';
|
|
3
|
+
export interface SubagentBranch {
|
|
4
|
+
id: string;
|
|
5
|
+
item: ChatSubagentItem;
|
|
6
|
+
children: ChatItem[];
|
|
7
|
+
nested: SubagentBranch[];
|
|
8
|
+
expanded: boolean;
|
|
9
|
+
}
|
|
10
|
+
export type TimelineRow = {
|
|
11
|
+
kind: 'user';
|
|
12
|
+
id: string;
|
|
13
|
+
item: ChatUserItem;
|
|
14
|
+
} | {
|
|
15
|
+
kind: 'turn-start';
|
|
16
|
+
id: string;
|
|
17
|
+
turn: ChatTurnItem;
|
|
18
|
+
label: string;
|
|
19
|
+
} | {
|
|
20
|
+
kind: 'assistant';
|
|
21
|
+
id: string;
|
|
22
|
+
item: ChatAssistantItem;
|
|
23
|
+
} | {
|
|
24
|
+
kind: 'report';
|
|
25
|
+
id: string;
|
|
26
|
+
text: string;
|
|
27
|
+
} | {
|
|
28
|
+
kind: 'thinking';
|
|
29
|
+
id: string;
|
|
30
|
+
item: ChatThinkingItem;
|
|
31
|
+
} | {
|
|
32
|
+
kind: 'work';
|
|
33
|
+
id: string;
|
|
34
|
+
tool: ChatToolItem;
|
|
35
|
+
} | {
|
|
36
|
+
kind: 'work-group';
|
|
37
|
+
id: string;
|
|
38
|
+
tools: ChatToolItem[];
|
|
39
|
+
summary: string;
|
|
40
|
+
expanded: boolean;
|
|
41
|
+
} | {
|
|
42
|
+
kind: 'work-live';
|
|
43
|
+
id: string;
|
|
44
|
+
tool: ChatToolItem;
|
|
45
|
+
} | {
|
|
46
|
+
kind: 'workflow';
|
|
47
|
+
id: string;
|
|
48
|
+
tool: ChatToolItem;
|
|
49
|
+
workflow: ChatWorkflow;
|
|
50
|
+
} | ({
|
|
51
|
+
kind: 'subagent';
|
|
52
|
+
} & SubagentBranch) | {
|
|
53
|
+
kind: 'approval';
|
|
54
|
+
id: string;
|
|
55
|
+
item: ChatApprovalItem;
|
|
56
|
+
} | {
|
|
57
|
+
kind: 'question';
|
|
58
|
+
id: string;
|
|
59
|
+
item: ChatQuestionItem;
|
|
60
|
+
} | {
|
|
61
|
+
kind: 'note';
|
|
62
|
+
id: string;
|
|
63
|
+
level: 'info' | 'warning' | 'error';
|
|
64
|
+
text: string;
|
|
65
|
+
from?: string;
|
|
66
|
+
} | {
|
|
67
|
+
kind: 'compaction';
|
|
68
|
+
id: string;
|
|
69
|
+
preTokens: number | null;
|
|
70
|
+
} | {
|
|
71
|
+
kind: 'changed-files';
|
|
72
|
+
id: string;
|
|
73
|
+
turnId: string;
|
|
74
|
+
tools: ChatToolItem[];
|
|
75
|
+
diff: ChatCheckpointDiff | null;
|
|
76
|
+
checkpoint: boolean;
|
|
77
|
+
} | {
|
|
78
|
+
kind: 'turn-fold';
|
|
79
|
+
id: string;
|
|
80
|
+
turn: ChatTurnItem;
|
|
81
|
+
label: string;
|
|
82
|
+
work: string[];
|
|
83
|
+
hiddenCount: number;
|
|
84
|
+
expanded: boolean;
|
|
85
|
+
} | {
|
|
86
|
+
kind: 'forks';
|
|
87
|
+
id: string;
|
|
88
|
+
turnId: string;
|
|
89
|
+
} | {
|
|
90
|
+
kind: 'working';
|
|
91
|
+
id: string;
|
|
92
|
+
startedAt: number;
|
|
93
|
+
} | {
|
|
94
|
+
kind: 'app-card';
|
|
95
|
+
id: string;
|
|
96
|
+
card: ThreadCard;
|
|
97
|
+
};
|
|
98
|
+
interface TimelineOptions {
|
|
99
|
+
expandedGroups: ReadonlySet<string>;
|
|
100
|
+
expandedTurns: ReadonlySet<string>;
|
|
101
|
+
expandedSubagents: ReadonlySet<string>;
|
|
102
|
+
activeTurnId: string | null;
|
|
103
|
+
forkedTurns?: ReadonlySet<string>;
|
|
104
|
+
}
|
|
105
|
+
export declare function isBlock(row: TimelineRow): boolean;
|
|
106
|
+
export declare function summarizeGroup(tools: ChatToolItem[]): string;
|
|
107
|
+
export declare function summarizeTurn(tools: readonly ChatToolItem[]): string[];
|
|
108
|
+
export declare function agentTurnLabel(turn: ChatTurnItem): string;
|
|
109
|
+
export declare function turnLabel(turn: ChatTurnItem, items?: readonly ChatItem[]): string;
|
|
110
|
+
export declare function findSubagentBranch(rows: readonly TimelineRow[], toolUseId: string): {
|
|
111
|
+
index: number;
|
|
112
|
+
branch: SubagentBranch;
|
|
113
|
+
} | null;
|
|
114
|
+
export declare function deriveTimelineRows(items: ChatItem[], options: TimelineOptions): TimelineRow[];
|
|
115
|
+
export {};
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import i18next from 'i18next';
|
|
2
|
+
import { abortedByMachine } from '@adecore/agent-contracts';
|
|
3
|
+
import { formatElapsedShort } from '@adecore/ui/format';
|
|
4
|
+
import { handbackReportOf } from './handback.js';
|
|
5
|
+
import { toolEntry } from './tool-catalog.js';
|
|
6
|
+
import { hasFileChanges, isFileChange } from './tools.js';
|
|
7
|
+
/*
|
|
8
|
+
* A turn runs in two rhythms. The tool lines are a list and read as one when they sit tight
|
|
9
|
+
* against each other; prose and cards are blocks and need room around them. Where the two meet,
|
|
10
|
+
* the block gap marks the seam, so an answer never looks glued to the call above it.
|
|
11
|
+
*/
|
|
12
|
+
const BLOCK_KINDS = new Set(['assistant', 'report', 'thinking', 'changed-files', 'compaction', 'app-card']);
|
|
13
|
+
export function isBlock(row) {
|
|
14
|
+
return BLOCK_KINDS.has(row.kind);
|
|
15
|
+
}
|
|
16
|
+
/* "Read 4 files", "Ran 2 commands", or "12 tool calls" when the run mixes kinds. */
|
|
17
|
+
export function summarizeGroup(tools) {
|
|
18
|
+
const names = new Set(tools.map((tool) => tool.name));
|
|
19
|
+
const only = names.size === 1 ? tools[0].name : null;
|
|
20
|
+
if (only !== null && toolEntry(only)?.grouped === true) {
|
|
21
|
+
return i18next.t(`agent-chat:group.tools.${only}`, { count: tools.length });
|
|
22
|
+
}
|
|
23
|
+
/* A run that only touches files says so once, whether it took one tool or three, and counts the
|
|
24
|
+
files rather than the calls: three edits to one file are one file edited. */
|
|
25
|
+
if (tools.every((tool) => isFileChange(tool.name))) {
|
|
26
|
+
const paths = new Set(tools.map((tool) => tool.input?.file_path ?? tool.id));
|
|
27
|
+
return i18next.t('agent-chat:group.edited', { count: paths.size });
|
|
28
|
+
}
|
|
29
|
+
if (only !== null) {
|
|
30
|
+
return i18next.t('agent-chat:group.calls', { name: only, count: tools.length });
|
|
31
|
+
}
|
|
32
|
+
return i18next.t('agent-chat:group.toolCalls', { count: tools.length });
|
|
33
|
+
}
|
|
34
|
+
/*
|
|
35
|
+
* What a folded turn did, a sentence per kind of call in the order it first came: "Read 11 files",
|
|
36
|
+
* "Searched 2 patterns". Every file change reads as one sentence, and calls without a sentence of
|
|
37
|
+
* their own are counted together at the end.
|
|
38
|
+
*/
|
|
39
|
+
export function summarizeTurn(tools) {
|
|
40
|
+
// Keyed by the sentence, so its place is where the first call of that kind came.
|
|
41
|
+
const counts = new Map();
|
|
42
|
+
const edited = new Set();
|
|
43
|
+
let other = 0;
|
|
44
|
+
for (const tool of tools) {
|
|
45
|
+
if (isFileChange(tool.name)) {
|
|
46
|
+
edited.add(tool.input?.file_path ?? tool.id);
|
|
47
|
+
counts.set('agent-chat:group.edited', edited.size);
|
|
48
|
+
}
|
|
49
|
+
else if (toolEntry(tool.name)?.grouped === true) {
|
|
50
|
+
const key = `agent-chat:group.tools.${tool.name}`;
|
|
51
|
+
counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
other += 1;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const parts = [...counts].map(([key, count]) => i18next.t(key, { count }));
|
|
58
|
+
if (other > 0) {
|
|
59
|
+
parts.push(i18next.t(parts.length === 0 ? 'agent-chat:group.toolCalls' : 'agent-chat:group.otherCalls', { count: other }));
|
|
60
|
+
}
|
|
61
|
+
return parts;
|
|
62
|
+
}
|
|
63
|
+
/*
|
|
64
|
+
* What a turn nobody asked for is about. The CLI wakes the agent when a background subagent settles
|
|
65
|
+
* and hands over its summary; without one all that is known is that the agent went on by itself.
|
|
66
|
+
*/
|
|
67
|
+
export function agentTurnLabel(turn) {
|
|
68
|
+
const about = (what) => (turn.label ? i18next.t('agent-chat:turn.about', { what, label: turn.label }) : what);
|
|
69
|
+
// A turn the machine opened with the results of tasks this chat gave; the label is their titles.
|
|
70
|
+
if (turn.taskIds !== undefined && turn.taskIds.length > 0) {
|
|
71
|
+
return about(i18next.t('agent-chat:turn.wokenByTask', { count: turn.taskIds.length }));
|
|
72
|
+
}
|
|
73
|
+
// A turn the machine opened over a message another node sent; the label names who sent it.
|
|
74
|
+
if (turn.messageFrom !== undefined && turn.messageFrom.length > 0) {
|
|
75
|
+
return about(i18next.t('agent-chat:turn.wokenByMessage', { count: turn.messageFrom.length }));
|
|
76
|
+
}
|
|
77
|
+
return turn.label ? i18next.t('agent-chat:turn.subagentFinished', { label: turn.label }) : i18next.t('agent-chat:turn.continued');
|
|
78
|
+
}
|
|
79
|
+
/* The items of the turn tell a turn a person stopped from one the machine ended after a restart. */
|
|
80
|
+
export function turnLabel(turn, items = []) {
|
|
81
|
+
const duration = formatElapsedShort((turn.endedAt ?? turn.createdAt) - turn.createdAt);
|
|
82
|
+
switch (turn.state) {
|
|
83
|
+
case 'aborted':
|
|
84
|
+
return abortedByMachine(turn, items) ? i18next.t('agent-chat:turn.stopped', { duration }) : i18next.t('agent-chat:turn.youStopped', { duration });
|
|
85
|
+
case 'error':
|
|
86
|
+
return i18next.t('agent-chat:turn.failed', { duration });
|
|
87
|
+
default:
|
|
88
|
+
return i18next.t('agent-chat:turn.worked', { duration });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// A subagent's own work, and an agent it opened, belong to its row, not to the thread; an old record has no row for it.
|
|
92
|
+
function parentOf(item) {
|
|
93
|
+
return item.kind === 'tool' || item.kind === 'assistant' || item.kind === 'subagent' ? (item.parentToolUseId ?? null) : null;
|
|
94
|
+
}
|
|
95
|
+
// Deeper than the CLI forwards any call; it also ends a chain of rows that would name each other.
|
|
96
|
+
const MAX_NESTING = 8;
|
|
97
|
+
function branchOf(item, options, children, depth = 0) {
|
|
98
|
+
const own = children.get(item.toolUseId) ?? [];
|
|
99
|
+
return {
|
|
100
|
+
id: item.id,
|
|
101
|
+
item,
|
|
102
|
+
children: own.filter((child) => child.kind !== 'subagent'),
|
|
103
|
+
nested: depth >= MAX_NESTING
|
|
104
|
+
? []
|
|
105
|
+
: own.filter((child) => child.kind === 'subagent').map((child) => branchOf(child, options, children, depth + 1)),
|
|
106
|
+
expanded: options.expandedSubagents.has(item.id)
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/* The branch a subagent's row sits in, its own or one it hangs under, anywhere in the thread's rows. */
|
|
110
|
+
export function findSubagentBranch(rows, toolUseId) {
|
|
111
|
+
const search = (branch) => {
|
|
112
|
+
if (branch.item.toolUseId === toolUseId) {
|
|
113
|
+
return branch;
|
|
114
|
+
}
|
|
115
|
+
for (const child of branch.nested) {
|
|
116
|
+
const found = search(child);
|
|
117
|
+
if (found) {
|
|
118
|
+
return found;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return null;
|
|
122
|
+
};
|
|
123
|
+
for (let index = 0; index < rows.length; index++) {
|
|
124
|
+
const row = rows[index];
|
|
125
|
+
const branch = row.kind === 'subagent' ? search(row) : null;
|
|
126
|
+
if (branch) {
|
|
127
|
+
return { index, branch };
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
/* What each subagent did, keyed by the call that spawned it, in the order it happened. */
|
|
133
|
+
function groupChildren(items) {
|
|
134
|
+
const children = new Map();
|
|
135
|
+
for (const item of items) {
|
|
136
|
+
const parent = parentOf(item);
|
|
137
|
+
if (parent === null) {
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
const bucket = children.get(parent);
|
|
141
|
+
if (bucket) {
|
|
142
|
+
bucket.push(item);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
children.set(parent, [item]);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return children;
|
|
149
|
+
}
|
|
150
|
+
function flushTools(buffer, rows, options) {
|
|
151
|
+
if (buffer.length === 0) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
const tools = buffer.splice(0);
|
|
155
|
+
const live = tools.filter((tool) => tool.state === 'running');
|
|
156
|
+
const settled = tools.filter((tool) => tool.state !== 'running');
|
|
157
|
+
if (settled.length === 1) {
|
|
158
|
+
rows.push({ kind: 'work', id: settled[0].id, tool: settled[0] });
|
|
159
|
+
}
|
|
160
|
+
else if (settled.length > 1) {
|
|
161
|
+
const id = `group-${settled[0].id}`;
|
|
162
|
+
const expanded = options.expandedGroups.has(id);
|
|
163
|
+
rows.push({ kind: 'work-group', id, tools: settled, summary: summarizeGroup(settled), expanded });
|
|
164
|
+
if (expanded) {
|
|
165
|
+
for (const tool of settled) {
|
|
166
|
+
rows.push({ kind: 'work', id: tool.id, tool });
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
for (const tool of live) {
|
|
171
|
+
rows.push({ kind: 'work-live', id: tool.id, tool });
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/* Rows for a run of items, in order, with tool runs folded and a subagent's work under its own row. */
|
|
175
|
+
function rowsForItems(items, options, children) {
|
|
176
|
+
const rows = [];
|
|
177
|
+
const tools = [];
|
|
178
|
+
for (const item of items) {
|
|
179
|
+
if (parentOf(item) !== null) {
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
const report = handbackReportOf(item);
|
|
183
|
+
if (item.kind === 'tool' && item.workflow !== undefined) {
|
|
184
|
+
flushTools(tools, rows, options);
|
|
185
|
+
rows.push({ kind: 'workflow', id: item.id, tool: item, workflow: item.workflow });
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
if (item.kind === 'tool' && report === null) {
|
|
189
|
+
tools.push(item);
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
if (report !== null) {
|
|
193
|
+
flushTools(tools, rows, options);
|
|
194
|
+
rows.push({ kind: 'report', id: item.id, text: report });
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
flushTools(tools, rows, options);
|
|
198
|
+
switch (item.kind) {
|
|
199
|
+
case 'subagent':
|
|
200
|
+
rows.push({ kind: 'subagent', ...branchOf(item, options, children) });
|
|
201
|
+
break;
|
|
202
|
+
case 'user':
|
|
203
|
+
rows.push({ kind: 'user', id: item.id, item });
|
|
204
|
+
break;
|
|
205
|
+
case 'assistant':
|
|
206
|
+
if (item.text !== '' || item.streaming) {
|
|
207
|
+
rows.push({ kind: 'assistant', id: item.id, item });
|
|
208
|
+
}
|
|
209
|
+
break;
|
|
210
|
+
case 'thinking':
|
|
211
|
+
rows.push({ kind: 'thinking', id: item.id, item });
|
|
212
|
+
break;
|
|
213
|
+
case 'approval':
|
|
214
|
+
// A pending one sits on the composer; only its outcome belongs in the transcript.
|
|
215
|
+
if (item.decision !== 'pending') {
|
|
216
|
+
rows.push({ kind: 'approval', id: item.id, item });
|
|
217
|
+
}
|
|
218
|
+
break;
|
|
219
|
+
case 'question':
|
|
220
|
+
if (item.state !== 'pending') {
|
|
221
|
+
rows.push({ kind: 'question', id: item.id, item });
|
|
222
|
+
}
|
|
223
|
+
break;
|
|
224
|
+
case 'note':
|
|
225
|
+
rows.push({ kind: 'note', id: item.id, level: item.level, text: item.text, ...(item.from === undefined ? {} : { from: item.from }) });
|
|
226
|
+
break;
|
|
227
|
+
case 'compaction':
|
|
228
|
+
rows.push({ kind: 'compaction', id: item.id, preTokens: item.preTokens });
|
|
229
|
+
break;
|
|
230
|
+
case 'turn':
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
flushTools(tools, rows, options);
|
|
235
|
+
return rows;
|
|
236
|
+
}
|
|
237
|
+
/* The card of a settled turn: the checkpoint diff when the host took one, else what the tool calls carry. */
|
|
238
|
+
function changedFilesRow(turn, items) {
|
|
239
|
+
const edits = items.filter((item) => item.kind === 'tool' && item.state === 'done' && isFileChange(item.name) && hasFileChanges(item));
|
|
240
|
+
const diff = turn.checkpointDiff ?? null;
|
|
241
|
+
const empty = diff === null ? edits.length === 0 : diff.files.length === 0;
|
|
242
|
+
if (empty) {
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
245
|
+
return { kind: 'changed-files', id: `files-${turn.id}`, turnId: turn.id, tools: edits, diff, checkpoint: turn.checkpoint !== undefined };
|
|
246
|
+
}
|
|
247
|
+
function lastAssistantRow(rows) {
|
|
248
|
+
for (let i = rows.length - 1; i >= 0; i--) {
|
|
249
|
+
const row = rows[i];
|
|
250
|
+
if (row.kind === 'assistant') {
|
|
251
|
+
return row;
|
|
252
|
+
}
|
|
253
|
+
if (row.kind !== 'note') {
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
/* The whole thread as rows; items without a turn (older records) are shown as they are. */
|
|
260
|
+
export function deriveTimelineRows(items, options) {
|
|
261
|
+
const rows = [];
|
|
262
|
+
const children = groupChildren(items);
|
|
263
|
+
// Items are grouped by turn, in order of first appearance; runs of turnless items keep their place.
|
|
264
|
+
const chunks = [];
|
|
265
|
+
const byTurn = new Map();
|
|
266
|
+
for (const item of items) {
|
|
267
|
+
if (item.turnId === null) {
|
|
268
|
+
const last = chunks[chunks.length - 1];
|
|
269
|
+
if (last && last.turnId === null) {
|
|
270
|
+
last.items.push(item);
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
chunks.push({ turnId: null, items: [item] });
|
|
274
|
+
}
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
let bucket = byTurn.get(item.turnId);
|
|
278
|
+
if (!bucket) {
|
|
279
|
+
bucket = [];
|
|
280
|
+
byTurn.set(item.turnId, bucket);
|
|
281
|
+
chunks.push({ turnId: item.turnId, items: bucket });
|
|
282
|
+
}
|
|
283
|
+
bucket.push(item);
|
|
284
|
+
}
|
|
285
|
+
for (const chunk of chunks) {
|
|
286
|
+
if (chunk.turnId === null) {
|
|
287
|
+
rows.push(...rowsForItems(chunk.items, options, children));
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
const turnId = chunk.turnId;
|
|
291
|
+
const turn = chunk.items.find((item) => item.kind === 'turn');
|
|
292
|
+
const user = chunk.items.filter((item) => item.kind === 'user');
|
|
293
|
+
const rest = chunk.items.filter((item) => item.kind !== 'user' && item.kind !== 'turn');
|
|
294
|
+
if (turn?.origin === 'agent') {
|
|
295
|
+
// The agent started this one itself, so there is no message of the person to show above it.
|
|
296
|
+
rows.push({ kind: 'turn-start', id: `start-${turnId}`, turn, label: agentTurnLabel(turn) });
|
|
297
|
+
}
|
|
298
|
+
rows.push(...rowsForItems(user, options, children));
|
|
299
|
+
const active = turnId === options.activeTurnId || turn?.state === 'running';
|
|
300
|
+
const work = rowsForItems(rest, options, children);
|
|
301
|
+
if (!turn || active) {
|
|
302
|
+
rows.push(...work);
|
|
303
|
+
if (active) {
|
|
304
|
+
rows.push({ kind: 'working', id: `working-${turnId}`, startedAt: turn?.createdAt ?? Date.now() });
|
|
305
|
+
}
|
|
306
|
+
continue;
|
|
307
|
+
}
|
|
308
|
+
// The closing answer stays visible; everything before it folds behind the label.
|
|
309
|
+
const finalAssistant = lastAssistantRow(work);
|
|
310
|
+
const before = finalAssistant ? work.slice(0, work.indexOf(finalAssistant)) : work;
|
|
311
|
+
// A workflow runs on past the turn that launched it, so its row stays in sight until it ends.
|
|
312
|
+
const standing = before.filter((row) => row.kind === 'workflow' && row.tool.state === 'running');
|
|
313
|
+
const folded = before.filter((row) => !standing.includes(row));
|
|
314
|
+
const expanded = options.expandedTurns.has(turnId);
|
|
315
|
+
if (folded.length > 0) {
|
|
316
|
+
const tools = rest.filter((item) => item.kind === 'tool' && parentOf(item) === null && handbackReportOf(item) === null);
|
|
317
|
+
rows.push({
|
|
318
|
+
kind: 'turn-fold',
|
|
319
|
+
id: `fold-${turnId}`,
|
|
320
|
+
turn,
|
|
321
|
+
label: turnLabel(turn, chunk.items),
|
|
322
|
+
work: summarizeTurn(tools),
|
|
323
|
+
hiddenCount: folded.length,
|
|
324
|
+
expanded
|
|
325
|
+
});
|
|
326
|
+
if (expanded) {
|
|
327
|
+
rows.push(...folded);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
rows.push(...standing);
|
|
331
|
+
const changed = changedFilesRow(turn, rest);
|
|
332
|
+
if (changed) {
|
|
333
|
+
rows.push(changed);
|
|
334
|
+
}
|
|
335
|
+
if (finalAssistant) {
|
|
336
|
+
rows.push(finalAssistant);
|
|
337
|
+
}
|
|
338
|
+
if (options.forkedTurns?.has(turnId) === true) {
|
|
339
|
+
rows.push({ kind: 'forks', id: `forks-${turnId}`, turnId });
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
return rows;
|
|
343
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type LucideIcon } from 'lucide-react';
|
|
2
|
+
export interface ToolEntry {
|
|
3
|
+
icon: LucideIcon;
|
|
4
|
+
summary: readonly string[];
|
|
5
|
+
grouped: boolean;
|
|
6
|
+
changesFiles: boolean;
|
|
7
|
+
readsImage: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare const TOOL_CATALOG: Record<string, ToolEntry>;
|
|
10
|
+
export declare function toolEntry(name: string): ToolEntry | undefined;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Bot, Eye, FolderSearch, Globe, ListTodo, Search, SquarePen, Terminal, Workflow, Zap } from 'lucide-react';
|
|
2
|
+
function entry(icon, summary, rest = {}) {
|
|
3
|
+
return {
|
|
4
|
+
icon,
|
|
5
|
+
summary,
|
|
6
|
+
grouped: true,
|
|
7
|
+
changesFiles: false,
|
|
8
|
+
readsImage: false,
|
|
9
|
+
...rest
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
/*
|
|
13
|
+
* The icon, the summary line, the group sentence and the file-changing flag of every tool the thread
|
|
14
|
+
* has a word for, in one table, because they used to sit in four and a name added to one of them was
|
|
15
|
+
* missing from the rest. A name that is not here still draws, reads and groups; it falls back to the
|
|
16
|
+
* wrench and to the first string of its input.
|
|
17
|
+
*/
|
|
18
|
+
export const TOOL_CATALOG = {
|
|
19
|
+
Read: entry(Eye, ['file_path'], { readsImage: true }),
|
|
20
|
+
// Only `readImagePath` ever had this one, which is why it has no sentence of its own yet.
|
|
21
|
+
NotebookRead: entry(Eye, ['file_path', 'notebook_path'], { grouped: false, readsImage: true }),
|
|
22
|
+
// These three read as "Edited 3 files" through `changesFiles`, so they carry no copy of that sentence.
|
|
23
|
+
Edit: entry(SquarePen, ['file_path'], { grouped: false, changesFiles: true }),
|
|
24
|
+
Write: entry(SquarePen, ['file_path'], { changesFiles: true }),
|
|
25
|
+
MultiEdit: entry(SquarePen, ['file_path'], { grouped: false, changesFiles: true }),
|
|
26
|
+
NotebookEdit: entry(SquarePen, ['file_path', 'notebook_path']),
|
|
27
|
+
// Codex reports a patch as the paths it touches; its own input carries no path of its own.
|
|
28
|
+
ApplyPatch: entry(SquarePen, ['summary'], { grouped: false, changesFiles: true }),
|
|
29
|
+
Bash: entry(Terminal, ['description', 'command']),
|
|
30
|
+
Grep: entry(Search, ['pattern']),
|
|
31
|
+
Glob: entry(FolderSearch, ['pattern']),
|
|
32
|
+
WebFetch: entry(Globe, ['url', 'query']),
|
|
33
|
+
WebSearch: entry(Globe, ['url', 'query']),
|
|
34
|
+
Task: entry(Bot, ['description']),
|
|
35
|
+
Agent: entry(Bot, ['description']),
|
|
36
|
+
Skill: entry(Zap, ['skill']),
|
|
37
|
+
// A plan is a list of objects, so there is no line to lift out of it.
|
|
38
|
+
TodoWrite: entry(ListTodo, []),
|
|
39
|
+
// Its input is the whole script; the line takes what the CLI says the workflow is about instead.
|
|
40
|
+
Workflow: entry(Workflow, [], { grouped: false })
|
|
41
|
+
};
|
|
42
|
+
export function toolEntry(name) {
|
|
43
|
+
return TOOL_CATALOG[name];
|
|
44
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ChatFileChange, ChatToolItem } from '@adecore/agent-contracts';
|
|
2
|
+
export interface FileChange {
|
|
3
|
+
path: string;
|
|
4
|
+
before: string;
|
|
5
|
+
after: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function toolSummary(name: string, input: unknown): string;
|
|
8
|
+
export declare function readImagePath(name: string, input: unknown): string | null;
|
|
9
|
+
export declare function fileChanges(name: string, input: unknown): FileChange[];
|
|
10
|
+
export declare function isFileChange(name: string): boolean;
|
|
11
|
+
export declare function unifiedChanges(tool: ChatToolItem): ChatFileChange[];
|
|
12
|
+
export declare function approvalChanges(input: unknown): ChatFileChange[];
|
|
13
|
+
export declare function hasFileChanges(tool: ChatToolItem): boolean;
|
|
14
|
+
export declare function toolStartedAt(tool: ChatToolItem): number;
|
|
15
|
+
export declare function liveOutput(tool: ChatToolItem): string | null;
|