@adecore/agents-react 0.0.1 → 0.17.0-beta.2
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 +61 -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 +212 -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 +262 -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 +212 -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,17 @@
|
|
|
1
|
+
import type { ChatItem } from '@adecore/agent-contracts';
|
|
2
|
+
export interface RecentChatMessage {
|
|
3
|
+
role: 'user' | 'assistant';
|
|
4
|
+
text: string;
|
|
5
|
+
createdAt: number;
|
|
6
|
+
}
|
|
7
|
+
export interface RecentChatMessages {
|
|
8
|
+
messages: RecentChatMessage[];
|
|
9
|
+
truncated: boolean;
|
|
10
|
+
}
|
|
11
|
+
type MessageItem = Extract<ChatItem, {
|
|
12
|
+
kind: 'user' | 'assistant';
|
|
13
|
+
}>;
|
|
14
|
+
export declare function recentMessages(eligible: readonly MessageItem[], limit: number): RecentChatMessages;
|
|
15
|
+
export declare function recentChatMessages(items: Record<string, ChatItem>, order: readonly string[], limit: number): RecentChatMessages;
|
|
16
|
+
export declare function recentSubagentMessages(items: readonly ChatItem[], limit: number): RecentChatMessages;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const MAX_TOTAL_CHARACTERS = 12_000;
|
|
2
|
+
const MAX_MESSAGE_CHARACTERS = 3_000;
|
|
3
|
+
function clipped(text) {
|
|
4
|
+
return text.length <= MAX_MESSAGE_CHARACTERS ? { text, truncated: false } : { text: `${text.slice(0, MAX_MESSAGE_CHARACTERS - 1)}…`, truncated: true };
|
|
5
|
+
}
|
|
6
|
+
function isMessage(item) {
|
|
7
|
+
return item !== undefined && (item.kind === 'user' || item.kind === 'assistant') && item.text.trim() !== '';
|
|
8
|
+
}
|
|
9
|
+
/* The last messages of a conversation already cut down to the ones worth reading, clipped to what a reader can take in. */
|
|
10
|
+
export function recentMessages(eligible, limit) {
|
|
11
|
+
const candidates = eligible.slice(-limit);
|
|
12
|
+
const messages = [];
|
|
13
|
+
let characters = 0;
|
|
14
|
+
let truncated = candidates.length < eligible.length;
|
|
15
|
+
for (const item of candidates.toReversed()) {
|
|
16
|
+
const message = clipped(item.text.trim());
|
|
17
|
+
const remaining = MAX_TOTAL_CHARACTERS - characters;
|
|
18
|
+
if (remaining <= 0) {
|
|
19
|
+
truncated = true;
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
const text = message.text.length <= remaining ? message.text : `${message.text.slice(0, Math.max(0, remaining - 1))}…`;
|
|
23
|
+
messages.unshift({ role: item.kind, text, createdAt: item.createdAt });
|
|
24
|
+
characters += text.length;
|
|
25
|
+
truncated ||= message.truncated || text.length < message.text.length;
|
|
26
|
+
}
|
|
27
|
+
return { messages, truncated };
|
|
28
|
+
}
|
|
29
|
+
/* A sub-agent's replies sit in the thread too, and belong to its own conversation rather than the chat's. */
|
|
30
|
+
export function recentChatMessages(items, order, limit) {
|
|
31
|
+
return recentMessages(order.map((id) => items[id]).filter((item) => isMessage(item) && !(item.kind === 'assistant' && item.parentToolUseId)), limit);
|
|
32
|
+
}
|
|
33
|
+
/* Everything in a sub-agent's conversation is its own, so nothing is left out for being nested. */
|
|
34
|
+
export function recentSubagentMessages(items, limit) {
|
|
35
|
+
return recentMessages(items.filter(isMessage), limit);
|
|
36
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { create } from 'zustand';
|
|
2
|
+
import { useChatScope } from '../scope.js';
|
|
3
|
+
/*
|
|
4
|
+
* Which turn a person answered "Keep full history" on, per chat. In memory only: the offer appears
|
|
5
|
+
* at most once per silence, so a reload asking again costs nothing, and a refusal is not a setting.
|
|
6
|
+
*/
|
|
7
|
+
const useDismissals = create(() => ({ byKey: {} }));
|
|
8
|
+
export function useResumeCompactionDismissal(chatId) {
|
|
9
|
+
const { keyOf } = useChatScope();
|
|
10
|
+
return useDismissals((s) => s.byKey[keyOf(chatId)] ?? null);
|
|
11
|
+
}
|
|
12
|
+
export function dismissResumeCompaction(scope, chatId, turnId) {
|
|
13
|
+
useDismissals.setState((s) => ({ byKey: { ...s.byKey, [scope.keyOf(chatId)]: turnId } }));
|
|
14
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import i18next from 'i18next';
|
|
2
|
+
import { RuntimeModeSchema } from '@adecore/agent-contracts';
|
|
3
|
+
/*
|
|
4
|
+
* The runtime modes in the order they are offered, shared by the composer's mode picker, the
|
|
5
|
+
* settings dialog and the agent menus. That order is the schema's, which the host reads as the
|
|
6
|
+
* rank from narrowest to widest. Only the ids live here: the words are in `modes.<id>` of the `chat`
|
|
7
|
+
* namespace, read when a surface draws one rather than when this module loads.
|
|
8
|
+
*/
|
|
9
|
+
export const RUNTIME_MODES = RuntimeModeSchema.options;
|
|
10
|
+
export function runtimeModeLabel(mode) {
|
|
11
|
+
return i18next.t(`agent-chat:modes.${mode}.label`);
|
|
12
|
+
}
|
|
13
|
+
export function runtimeModeHint(mode) {
|
|
14
|
+
return i18next.t(`agent-chat:modes.${mode}.hint`);
|
|
15
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type ChatDraft } from './drafts.js';
|
|
2
|
+
export declare const STASH_SHORTCUT: import("@adecore/ui").Shortcut;
|
|
3
|
+
export declare const STASH_LIMIT = 20;
|
|
4
|
+
export interface StashedAttachment {
|
|
5
|
+
name: string;
|
|
6
|
+
mime: string;
|
|
7
|
+
size: number;
|
|
8
|
+
}
|
|
9
|
+
export interface StashedPrompt {
|
|
10
|
+
id: string;
|
|
11
|
+
text: string;
|
|
12
|
+
mentions: string[];
|
|
13
|
+
skills: string[];
|
|
14
|
+
attachments: StashedAttachment[];
|
|
15
|
+
createdAt: number;
|
|
16
|
+
}
|
|
17
|
+
export declare function parseStash(raw: string | null): StashedPrompt[];
|
|
18
|
+
export declare function withStashed(prompts: StashedPrompt[], entry: StashedPrompt): StashedPrompt[];
|
|
19
|
+
export declare function stashedFrom(draft: ChatDraft, id: string, now: number): StashedPrompt | null;
|
|
20
|
+
export declare const useStash: import("zustand").UseBoundStore<import("zustand").StoreApi<{
|
|
21
|
+
prompts: StashedPrompt[];
|
|
22
|
+
}>>;
|
|
23
|
+
export declare function stashDraft(draft: ChatDraft): boolean;
|
|
24
|
+
export declare function forgetStashed(id: string): void;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { chatStorageKey, chatStorageLegacyKeys, createChatStore } from '../storage.js';
|
|
2
|
+
import { uploadBytes } from './attachments.js';
|
|
3
|
+
import { isEmptyDraft } from './drafts.js';
|
|
4
|
+
import { isRecord } from './logic/json.js';
|
|
5
|
+
import { persistedJson } from './persisted-json.js';
|
|
6
|
+
import { withQuote } from './quote.js';
|
|
7
|
+
import { shortcut } from '@adecore/ui';
|
|
8
|
+
/* Puts the draft away, or takes the last one back on an empty box. */
|
|
9
|
+
export const STASH_SHORTCUT = shortcut('Mod+S');
|
|
10
|
+
const storageKey = () => chatStorageKey('stash');
|
|
11
|
+
// Past this the list is an archive nobody reads; the oldest entry makes room for a new one.
|
|
12
|
+
export const STASH_LIMIT = 20;
|
|
13
|
+
function strings(value) {
|
|
14
|
+
return Array.isArray(value) ? value.filter((entry) => typeof entry === 'string') : [];
|
|
15
|
+
}
|
|
16
|
+
function attachments(value) {
|
|
17
|
+
if (!Array.isArray(value)) {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
return value.filter(isRecord).map((entry) => ({
|
|
21
|
+
name: typeof entry.name === 'string' ? entry.name : '',
|
|
22
|
+
mime: typeof entry.mime === 'string' ? entry.mime : '',
|
|
23
|
+
size: typeof entry.size === 'number' ? entry.size : 0
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
26
|
+
/* Only the fields we know today, so anything an older or a broken write left behind falls away here. */
|
|
27
|
+
export function parseStash(raw) {
|
|
28
|
+
if (raw === null) {
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
const stored = JSON.parse(raw);
|
|
33
|
+
if (!Array.isArray(stored)) {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
return stored
|
|
37
|
+
.filter(isRecord)
|
|
38
|
+
.filter((entry) => typeof entry.id === 'string' && typeof entry.text === 'string')
|
|
39
|
+
.map((entry) => ({
|
|
40
|
+
id: entry.id,
|
|
41
|
+
text: entry.text,
|
|
42
|
+
mentions: strings(entry.mentions),
|
|
43
|
+
skills: strings(entry.skills),
|
|
44
|
+
attachments: attachments(entry.attachments),
|
|
45
|
+
createdAt: typeof entry.createdAt === 'number' ? entry.createdAt : 0
|
|
46
|
+
}))
|
|
47
|
+
.slice(0, STASH_LIMIT);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/* Newest first, capped: the entry that has been waiting longest is the one nobody comes back for. */
|
|
54
|
+
export function withStashed(prompts, entry) {
|
|
55
|
+
return [entry, ...prompts].slice(0, STASH_LIMIT);
|
|
56
|
+
}
|
|
57
|
+
/* What a draft looks like on the shelf, its quote folded into the text; null when there is nothing worth putting there. */
|
|
58
|
+
export function stashedFrom(draft, id, now) {
|
|
59
|
+
if (isEmptyDraft(draft)) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
id,
|
|
64
|
+
text: withQuote(draft.quote, draft.text),
|
|
65
|
+
mentions: [...draft.mentions],
|
|
66
|
+
skills: [...draft.skills],
|
|
67
|
+
attachments: draft.attachments.map((attachment) => ({ name: attachment.name, mime: attachment.mime, size: uploadBytes(attachment) })),
|
|
68
|
+
createdAt: now
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
const storage = persistedJson(storageKey, parseStash, [], () => chatStorageLegacyKeys('stash'));
|
|
72
|
+
/*
|
|
73
|
+
* Prompts put aside for later can move to another chat, so the shelf is shared across chats.
|
|
74
|
+
*/
|
|
75
|
+
export const useStash = createChatStore(() => ({ prompts: [] }), (store) => store.setState({ prompts: storage.read() }));
|
|
76
|
+
function write(prompts) {
|
|
77
|
+
useStash.setState({ prompts });
|
|
78
|
+
storage.write(prompts);
|
|
79
|
+
}
|
|
80
|
+
/* Puts a draft on the shelf; false when the composer held nothing to put there. */
|
|
81
|
+
export function stashDraft(draft) {
|
|
82
|
+
const entry = stashedFrom(draft, `stash-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`, Date.now());
|
|
83
|
+
if (!entry) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
write(withStashed(useStash.getState().prompts, entry));
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
export function forgetStashed(id) {
|
|
90
|
+
write(useStash.getState().prompts.filter((entry) => entry.id !== id));
|
|
91
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { ChatItem, ChatSubagentResult } from '@adecore/agent-contracts';
|
|
2
|
+
import { type ChatTransport } from '../transport.js';
|
|
3
|
+
export declare const SUBAGENT_PAGE = 60;
|
|
4
|
+
export interface SubagentConversationState {
|
|
5
|
+
status: 'loading' | 'ready' | 'failed';
|
|
6
|
+
items: ChatItem[];
|
|
7
|
+
source: ChatSubagentResult['source'] | null;
|
|
8
|
+
context: NonNullable<ChatSubagentResult['context']> | null;
|
|
9
|
+
cursor: string | null;
|
|
10
|
+
live: boolean;
|
|
11
|
+
loadingEarlier: boolean;
|
|
12
|
+
error: string | null;
|
|
13
|
+
unsupported: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare const INITIAL_CONVERSATION: SubagentConversationState;
|
|
16
|
+
export declare function mergeNewest(current: ChatItem[], currentCursor: string | null, page: ChatItem[], pageCursor: string | null): {
|
|
17
|
+
items: ChatItem[];
|
|
18
|
+
cursor: string | null;
|
|
19
|
+
};
|
|
20
|
+
export declare class SubagentConversation {
|
|
21
|
+
private readonly transport;
|
|
22
|
+
private readonly chatId;
|
|
23
|
+
private readonly toolUseId;
|
|
24
|
+
private readonly onChange;
|
|
25
|
+
private readonly unsubscribe;
|
|
26
|
+
private state;
|
|
27
|
+
private disposed;
|
|
28
|
+
private queue;
|
|
29
|
+
private refreshWaiting;
|
|
30
|
+
private earlier;
|
|
31
|
+
constructor(transport: ChatTransport, chatId: string, toolUseId: string, onChange: (state: SubagentConversationState) => void);
|
|
32
|
+
get current(): SubagentConversationState;
|
|
33
|
+
start(): Promise<void>;
|
|
34
|
+
refresh(): Promise<void>;
|
|
35
|
+
loadEarlier(): Promise<void>;
|
|
36
|
+
dispose(): void;
|
|
37
|
+
private readNewest;
|
|
38
|
+
private ask;
|
|
39
|
+
private enqueue;
|
|
40
|
+
private set;
|
|
41
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import i18next from 'i18next';
|
|
2
|
+
import { errorCode, isConnectionError } from '../transport.js';
|
|
3
|
+
// What the panel opens on: the newest end of the conversation, which is where an agent that works is.
|
|
4
|
+
export const SUBAGENT_PAGE = 60;
|
|
5
|
+
export const INITIAL_CONVERSATION = {
|
|
6
|
+
status: 'loading',
|
|
7
|
+
items: [],
|
|
8
|
+
source: null,
|
|
9
|
+
context: null,
|
|
10
|
+
cursor: null,
|
|
11
|
+
live: false,
|
|
12
|
+
loadingEarlier: false,
|
|
13
|
+
error: null,
|
|
14
|
+
unsupported: false
|
|
15
|
+
};
|
|
16
|
+
/*
|
|
17
|
+
* The newest page laid over what is on screen. An item that is already there is replaced where it
|
|
18
|
+
* stands and a new one goes after them all. A page that shares nothing with what is held means more
|
|
19
|
+
* happened than one page holds, so what is held is dropped for it rather than shown with a hole.
|
|
20
|
+
*/
|
|
21
|
+
export function mergeNewest(current, currentCursor, page, pageCursor) {
|
|
22
|
+
const known = new Map(current.map((item, index) => [item.id, index]));
|
|
23
|
+
if (current.length > 0 && page.length > 0 && !page.some((item) => known.has(item.id))) {
|
|
24
|
+
return { items: page, cursor: pageCursor };
|
|
25
|
+
}
|
|
26
|
+
const items = [...current];
|
|
27
|
+
for (const item of page) {
|
|
28
|
+
const index = known.get(item.id);
|
|
29
|
+
if (index === undefined) {
|
|
30
|
+
items.push(item);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
items[index] = item;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return { items, cursor: current.length === 0 ? pageCursor : currentCursor };
|
|
37
|
+
}
|
|
38
|
+
function messageOf(error) {
|
|
39
|
+
return error instanceof Error ? error.message : i18next.t('agent-chat:subagents.noAnswer');
|
|
40
|
+
}
|
|
41
|
+
/*
|
|
42
|
+
* One subagent's conversation as a panel follows it. Opening asks for the newest page and holds the
|
|
43
|
+
* conversation on the machine, which then says whenever it grew; each time, the newest page is asked
|
|
44
|
+
* again and laid over what is there. A socket that comes back holds it again, and letting go is the
|
|
45
|
+
* last thing it says.
|
|
46
|
+
*/
|
|
47
|
+
export class SubagentConversation {
|
|
48
|
+
transport;
|
|
49
|
+
chatId;
|
|
50
|
+
toolUseId;
|
|
51
|
+
onChange;
|
|
52
|
+
unsubscribe = [];
|
|
53
|
+
state = INITIAL_CONVERSATION;
|
|
54
|
+
disposed = false;
|
|
55
|
+
// One request at a time, so a refresh never lands under an older page that arrived after it.
|
|
56
|
+
queue = Promise.resolve();
|
|
57
|
+
refreshWaiting = false;
|
|
58
|
+
earlier = null;
|
|
59
|
+
constructor(transport, chatId, toolUseId, onChange) {
|
|
60
|
+
this.transport = transport;
|
|
61
|
+
this.chatId = chatId;
|
|
62
|
+
this.toolUseId = toolUseId;
|
|
63
|
+
this.onChange = onChange;
|
|
64
|
+
}
|
|
65
|
+
get current() {
|
|
66
|
+
return this.state;
|
|
67
|
+
}
|
|
68
|
+
start() {
|
|
69
|
+
this.unsubscribe.push(this.transport.on('chat.subagentChanged', (event) => {
|
|
70
|
+
if (event.chatId === this.chatId && event.toolUseId === this.toolUseId) {
|
|
71
|
+
void this.refresh();
|
|
72
|
+
}
|
|
73
|
+
}), this.transport.subscribeStatus((status) => {
|
|
74
|
+
if (status === 'open') {
|
|
75
|
+
void this.enqueue(() => this.readNewest(true));
|
|
76
|
+
}
|
|
77
|
+
}));
|
|
78
|
+
return this.enqueue(() => this.readNewest(true));
|
|
79
|
+
}
|
|
80
|
+
/* The newest page again; calls that arrive while one waits become that one. */
|
|
81
|
+
refresh() {
|
|
82
|
+
if (this.refreshWaiting) {
|
|
83
|
+
return this.queue;
|
|
84
|
+
}
|
|
85
|
+
this.refreshWaiting = true;
|
|
86
|
+
return this.enqueue(() => {
|
|
87
|
+
this.refreshWaiting = false;
|
|
88
|
+
return this.readNewest(false);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
loadEarlier() {
|
|
92
|
+
// A page on its way answers every call made meanwhile; a scroll asks for one on every frame.
|
|
93
|
+
this.earlier ??= this.enqueue(async () => {
|
|
94
|
+
const cursor = this.state.cursor;
|
|
95
|
+
if (cursor === null) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
this.set({ loadingEarlier: true });
|
|
99
|
+
try {
|
|
100
|
+
const page = await this.ask({ cursor, limit: SUBAGENT_PAGE });
|
|
101
|
+
this.set({ items: [...page.items, ...this.state.items], cursor: page.history.cursor, live: page.live, loadingEarlier: false });
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
if (errorCode(error) === 'history-expired') {
|
|
105
|
+
// The record was written again under this panel; what it holds now is the only truth.
|
|
106
|
+
this.set({ items: [], cursor: null, loadingEarlier: false });
|
|
107
|
+
await this.readNewest(false);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
this.set({ loadingEarlier: false, error: messageOf(error) });
|
|
111
|
+
}
|
|
112
|
+
}).finally(() => {
|
|
113
|
+
this.earlier = null;
|
|
114
|
+
});
|
|
115
|
+
return this.earlier;
|
|
116
|
+
}
|
|
117
|
+
dispose() {
|
|
118
|
+
if (this.disposed) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
this.disposed = true;
|
|
122
|
+
for (const off of this.unsubscribe.splice(0)) {
|
|
123
|
+
off();
|
|
124
|
+
}
|
|
125
|
+
if (this.transport.status === 'open') {
|
|
126
|
+
void this.transport.request('chat.subagent', { chatId: this.chatId, toolUseId: this.toolUseId, limit: 1, watch: false }).catch(() => undefined);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async readNewest(watch) {
|
|
130
|
+
try {
|
|
131
|
+
const page = await this.ask({ limit: SUBAGENT_PAGE, ...(watch ? { watch: true } : {}) });
|
|
132
|
+
const merged = mergeNewest(this.state.items, this.state.cursor, page.items, page.history.cursor);
|
|
133
|
+
this.set({
|
|
134
|
+
status: 'ready',
|
|
135
|
+
items: merged.items,
|
|
136
|
+
cursor: merged.cursor,
|
|
137
|
+
live: page.live,
|
|
138
|
+
source: page.source,
|
|
139
|
+
context: page.context ?? null,
|
|
140
|
+
error: null
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
if (this.state.status === 'ready' && isConnectionError(error)) {
|
|
145
|
+
// What is on screen stays; the socket that comes back asks again.
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
const unsupported = errorCode(error) === 'unknown-request';
|
|
149
|
+
this.set({ status: 'failed', error: messageOf(error), unsupported });
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
ask(extra) {
|
|
153
|
+
return this.transport.request('chat.subagent', { chatId: this.chatId, toolUseId: this.toolUseId, ...extra });
|
|
154
|
+
}
|
|
155
|
+
enqueue(work) {
|
|
156
|
+
const next = this.queue.then(() => (this.disposed ? undefined : work()));
|
|
157
|
+
this.queue = next.catch(() => undefined);
|
|
158
|
+
return next;
|
|
159
|
+
}
|
|
160
|
+
set(patch) {
|
|
161
|
+
if (this.disposed) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
this.state = { ...this.state, ...patch };
|
|
165
|
+
this.onChange(this.state);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ChatInfo, ChatItem, ChatSubagentItem } from '@adecore/agent-contracts';
|
|
2
|
+
import type { StatusWord } from '../agents/status-look.js';
|
|
3
|
+
import type { SubagentTask } from '../host.js';
|
|
4
|
+
export declare function subagentTitle(item: ChatSubagentItem): string;
|
|
5
|
+
export declare function subagentFacts(item: ChatSubagentItem, modelName: string | null): string[];
|
|
6
|
+
export declare function taskIdOf(item: ChatSubagentItem): string | null;
|
|
7
|
+
export declare function statusWordOf(item: ChatSubagentItem, task: SubagentTask | null): StatusWord;
|
|
8
|
+
export type TaskRowState = StatusWord | 'waiting';
|
|
9
|
+
export declare function taskRowStateOf(item: ChatSubagentItem, task: SubagentTask | null, child: ChatInfo | undefined): TaskRowState;
|
|
10
|
+
export declare function flyoutSubagents(order: readonly string[], structure: Readonly<Record<string, ChatItem>>): ChatSubagentItem[];
|
|
11
|
+
export declare function summaryWordOf(words: readonly StatusWord[]): StatusWord;
|
|
12
|
+
export declare function badgeCountOf(words: readonly StatusWord[]): number;
|
|
13
|
+
export declare function entryTimeOf(item: ChatSubagentItem, task: SubagentTask | null, now: number): string;
|
|
14
|
+
export type SubagentStop = 'task' | 'mark';
|
|
15
|
+
export declare function stopOf(item: ChatSubagentItem, turnRunning: boolean): SubagentStop | null;
|
|
16
|
+
export declare function stopLabel(stop: SubagentStop): string;
|
|
17
|
+
export type ComposerStop = 'turn' | 'turn-and-subagents';
|
|
18
|
+
export declare function composerStopOf(shiftKey: boolean): ComposerStop;
|
|
19
|
+
export declare function composerStopLabel(): string;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import i18next from 'i18next';
|
|
2
|
+
import { formatMoment, formatElapsedShort, formatTokens } from '@adecore/ui/format';
|
|
3
|
+
export function subagentTitle(item) {
|
|
4
|
+
return item.description || item.summary || item.subagentType || i18next.t('agent-chat:rows.subagent.label');
|
|
5
|
+
}
|
|
6
|
+
/* What the bar over a sub-agent's conversation says of it beside its state and its time; the model is named by the caller, which has the catalog. */
|
|
7
|
+
export function subagentFacts(item, modelName) {
|
|
8
|
+
return [
|
|
9
|
+
modelName,
|
|
10
|
+
item.subagentType,
|
|
11
|
+
item.background ? i18next.t('agent-chat:rows.subagent.background') : null,
|
|
12
|
+
item.usage !== null && item.usage.totalTokens > 0
|
|
13
|
+
? i18next.t('agent-chat:subagents.info.tokens', { tokens: formatTokens(item.usage.totalTokens) })
|
|
14
|
+
: null,
|
|
15
|
+
item.usage !== null && item.usage.toolUses > 0 ? i18next.t('agent-chat:group.toolCalls', { count: item.usage.toolUses }) : null
|
|
16
|
+
].filter((fact) => fact !== null && fact !== '');
|
|
17
|
+
}
|
|
18
|
+
/* The task a row stands for, whose id the host wrote into the row's own. */
|
|
19
|
+
export function taskIdOf(item) {
|
|
20
|
+
return item.origin === 'ruimte' && item.id.startsWith('task-') ? item.id.slice(5) : null;
|
|
21
|
+
}
|
|
22
|
+
/* A cancelled task is a failed row on the wire and a paused one a running row, and only the task itself still says which it is. */
|
|
23
|
+
export function statusWordOf(item, task) {
|
|
24
|
+
if (item.status === 'failed' && task?.status === 'cancelled') {
|
|
25
|
+
return 'cancelled';
|
|
26
|
+
}
|
|
27
|
+
if (item.status === 'running' && task?.status === 'open' && task.paused !== undefined) {
|
|
28
|
+
return 'paused';
|
|
29
|
+
}
|
|
30
|
+
return item.status;
|
|
31
|
+
}
|
|
32
|
+
export function taskRowStateOf(item, task, child) {
|
|
33
|
+
const word = statusWordOf(item, task);
|
|
34
|
+
if (word === 'running' && (child?.status === 'needs-you' || (child?.requests?.length ?? 0) > 0)) {
|
|
35
|
+
return 'waiting';
|
|
36
|
+
}
|
|
37
|
+
return word;
|
|
38
|
+
}
|
|
39
|
+
/*
|
|
40
|
+
* What the flyout over the composer lists: every sub-agent still at work, and the ones that settled
|
|
41
|
+
* since the last message, so a finished batch stays until the next message is sent. That includes an
|
|
42
|
+
* older row a message woke again. A settled one from before that message stays too while a sibling of
|
|
43
|
+
* its turn still runs. Older ones are only in the thread.
|
|
44
|
+
*/
|
|
45
|
+
export function flyoutSubagents(order, structure) {
|
|
46
|
+
const lastMessage = order.findLastIndex((id) => structure[id]?.kind === 'user');
|
|
47
|
+
const lastMessageAt = lastMessage < 0 ? null : (structure[order[lastMessage]]?.createdAt ?? null);
|
|
48
|
+
const items = order.flatMap((id, index) => {
|
|
49
|
+
const item = structure[id];
|
|
50
|
+
return item?.kind === 'subagent' ? [{ item, index }] : [];
|
|
51
|
+
});
|
|
52
|
+
const turns = new Set(items.flatMap(({ item }) => (item.status === 'running' && item.turnId !== null ? [item.turnId] : [])));
|
|
53
|
+
return items
|
|
54
|
+
.filter(({ item, index }) => item.status === 'running' ||
|
|
55
|
+
index > lastMessage ||
|
|
56
|
+
(lastMessageAt !== null && item.finishedAt !== null && item.finishedAt > lastMessageAt) ||
|
|
57
|
+
(item.turnId !== null && turns.has(item.turnId)))
|
|
58
|
+
.map(({ item }) => item);
|
|
59
|
+
}
|
|
60
|
+
/* The one state the badge shows for all of them: work in progress first, then work held up, then whatever went wrong. */
|
|
61
|
+
export function summaryWordOf(words) {
|
|
62
|
+
return ['running', 'paused', 'failed', 'cancelled'].find((word) => words.includes(word)) ?? 'done';
|
|
63
|
+
}
|
|
64
|
+
/* The number on the badge: the ones still at work, a paused one included, and all of them once none is. */
|
|
65
|
+
export function badgeCountOf(words) {
|
|
66
|
+
const active = words.filter((word) => word === 'running' || word === 'paused').length;
|
|
67
|
+
return active > 0 ? active : words.length;
|
|
68
|
+
}
|
|
69
|
+
/* The time on the right of an entry: how long it has run so far, or how long it took once it settled. */
|
|
70
|
+
export function entryTimeOf(item, task, now) {
|
|
71
|
+
// A task's own record says when it was given and settled; the row copies those, but may lag behind it.
|
|
72
|
+
const startedAt = task?.createdAt ?? item.startedAt;
|
|
73
|
+
const finishedAt = task === null ? item.finishedAt : (task.settledAt ?? item.finishedAt);
|
|
74
|
+
const word = statusWordOf(item, task);
|
|
75
|
+
if (word === 'paused') {
|
|
76
|
+
const until = task?.paused?.until;
|
|
77
|
+
return until === undefined
|
|
78
|
+
? i18next.t('agent-chat:common.status.paused')
|
|
79
|
+
: i18next.t('agent-chat:activity.pausedUntil', { time: formatMoment(until, now) });
|
|
80
|
+
}
|
|
81
|
+
if (item.status === 'running') {
|
|
82
|
+
return startedAt > 0 ? formatElapsedShort(now - startedAt) : '';
|
|
83
|
+
}
|
|
84
|
+
if (startedAt <= 0 || finishedAt === null || finishedAt < startedAt) {
|
|
85
|
+
return i18next.t(`agent-chat:common.status.${word}`);
|
|
86
|
+
}
|
|
87
|
+
return i18next.t(`agent-chat:activity.took.${word}`, { duration: formatElapsedShort(finishedAt - startedAt) });
|
|
88
|
+
}
|
|
89
|
+
export function stopOf(item, turnRunning) {
|
|
90
|
+
if (item.status !== 'running') {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
if (item.origin === 'ruimte') {
|
|
94
|
+
return item.childId === undefined ? null : 'task';
|
|
95
|
+
}
|
|
96
|
+
return turnRunning ? null : 'mark';
|
|
97
|
+
}
|
|
98
|
+
export function stopLabel(stop) {
|
|
99
|
+
return stop === 'task' ? i18next.t('agent-chat:subagents.stop.task') : i18next.t('agent-chat:subagents.stop.mark');
|
|
100
|
+
}
|
|
101
|
+
export function composerStopOf(shiftKey) {
|
|
102
|
+
return shiftKey ? 'turn-and-subagents' : 'turn';
|
|
103
|
+
}
|
|
104
|
+
export function composerStopLabel() {
|
|
105
|
+
return i18next.t('agent-chat:composer.stop');
|
|
106
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { create } from 'zustand';
|
|
2
|
+
/*
|
|
3
|
+
* Whether a host can open a subagent's conversation is learned by asking once rather than from a
|
|
4
|
+
* version: the first refusal hides the button on that host's rows that carry no pointer of their own.
|
|
5
|
+
*/
|
|
6
|
+
export const useSubagentSupport = create((set, get) => ({
|
|
7
|
+
unsupported: {},
|
|
8
|
+
markUnsupported(scopeId) {
|
|
9
|
+
if (get().unsupported[scopeId]) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
set({ unsupported: { ...get().unsupported, [scopeId]: true } });
|
|
13
|
+
}
|
|
14
|
+
}));
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { ChatItem, ChatSubagentItem } from '@adecore/agent-contracts';
|
|
2
|
+
export interface SubagentStep {
|
|
3
|
+
toolUseId: string;
|
|
4
|
+
description: string;
|
|
5
|
+
}
|
|
6
|
+
export type SubagentTrail = readonly SubagentStep[];
|
|
7
|
+
export interface BreadcrumbStep {
|
|
8
|
+
label: string;
|
|
9
|
+
depth: number;
|
|
10
|
+
current: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare const MAIN_AGENT: SubagentTrail;
|
|
13
|
+
export declare function crumbOf(item: ChatSubagentItem): SubagentStep;
|
|
14
|
+
export declare function openFromMain(step: SubagentStep): SubagentTrail;
|
|
15
|
+
export declare function openBelow(trail: SubagentTrail, step: SubagentStep): SubagentTrail;
|
|
16
|
+
export declare function trailTo(trail: SubagentTrail, depth: number): SubagentTrail;
|
|
17
|
+
export declare function stepBack(trail: SubagentTrail): SubagentTrail;
|
|
18
|
+
export declare function composerWrites(trail: SubagentTrail): boolean;
|
|
19
|
+
export declare function breadcrumbOf(trail: SubagentTrail): BreadcrumbStep[];
|
|
20
|
+
export declare function canOpenSubagent(item: ChatSubagentItem, machineRefused: boolean): boolean;
|
|
21
|
+
export declare function subagentOf(structure: Readonly<Record<string, ChatItem>>, toolUseId: string): ChatSubagentItem | null;
|
|
22
|
+
export declare function openableSubagents(order: readonly string[], structure: Record<string, ChatItem>, machineRefused: boolean): ChatSubagentItem[];
|
|
23
|
+
interface SubagentViewStore {
|
|
24
|
+
trails: Record<string, SubagentTrail>;
|
|
25
|
+
show(key: string, trail: SubagentTrail): void;
|
|
26
|
+
back(key: string): boolean;
|
|
27
|
+
}
|
|
28
|
+
export declare const useSubagentView: import("zustand").UseBoundStore<import("zustand").StoreApi<SubagentViewStore>>;
|
|
29
|
+
export declare function useSubagentTrail(chatId: string): {
|
|
30
|
+
trail: SubagentTrail;
|
|
31
|
+
show(trail: SubagentTrail): void;
|
|
32
|
+
};
|
|
33
|
+
export declare function useOpenableSubagents(chatId: string): ChatSubagentItem[];
|
|
34
|
+
export declare function useSubagentItem(chatId: string, toolUseId: string): ChatSubagentItem | null;
|
|
35
|
+
export {};
|