@adecore/agents-react 0.23.1 → 0.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -11
- package/dist/agents/AccountDot.js +3 -1
- package/dist/agents/accounts.d.ts +3 -2
- package/dist/agents/accounts.js +5 -6
- package/dist/chat/actions.d.ts +2 -2
- package/dist/chat/actions.js +8 -5
- package/dist/chat/bookmarks.d.ts +5 -3
- package/dist/chat/bookmarks.js +13 -14
- package/dist/chat/chat-client.d.ts +1 -0
- package/dist/chat/chat-client.js +7 -0
- package/dist/chat/composer-send.d.ts +3 -0
- package/dist/chat/composer-send.js +22 -0
- package/dist/chat/forks.js +22 -5
- package/dist/chat/index.d.ts +31 -0
- package/dist/chat/index.js +28 -0
- package/dist/chat/logic/embedded-code.d.ts +8 -0
- package/dist/chat/logic/embedded-code.js +371 -0
- package/dist/chat/logic/fork.js +1 -0
- package/dist/chat/logic/goal.d.ts +6 -0
- package/dist/chat/logic/goal.js +26 -0
- package/dist/chat/logic/scrubber.d.ts +1 -1
- package/dist/chat/logic/scrubber.js +6 -5
- package/dist/chat/logic/thought.d.ts +3 -0
- package/dist/chat/logic/thought.js +35 -0
- package/dist/chat/logic/thread-cards.js +2 -0
- package/dist/chat/logic/timeline.d.ts +5 -0
- package/dist/chat/logic/timeline.js +22 -1
- package/dist/chat/logic/tool-catalog.d.ts +1 -0
- package/dist/chat/logic/tool-catalog.js +3 -1
- package/dist/chat/logic/tools.d.ts +14 -0
- package/dist/chat/logic/tools.js +57 -0
- package/dist/chat/preferences.d.ts +6 -0
- package/dist/chat/preferences.js +19 -3
- package/dist/chat/reading-width.d.ts +9 -0
- package/dist/chat/reading-width.js +27 -0
- package/dist/chat/send-key.d.ts +10 -0
- package/dist/chat/send-key.js +24 -0
- package/dist/chat/ui/BookmarkMarker.js +4 -2
- package/dist/chat/ui/BookmarkSubmenu.js +4 -3
- package/dist/chat/ui/ChatActivity.js +14 -10
- package/dist/chat/ui/ChatReferenceChip.js +3 -4
- package/dist/chat/ui/CodeBlock.d.ts +2 -1
- package/dist/chat/ui/CodeBlock.js +14 -96
- package/dist/chat/ui/Composer.d.ts +1 -1
- package/dist/chat/ui/Composer.js +130 -907
- package/dist/chat/ui/ComposerInput.js +5 -4
- package/dist/chat/ui/EditDiff.js +3 -2
- package/dist/chat/ui/GoalDock.d.ts +9 -0
- package/dist/chat/ui/GoalDock.js +63 -0
- package/dist/chat/ui/LimitState.js +5 -3
- package/dist/chat/ui/Markdown.d.ts +2 -1
- package/dist/chat/ui/Markdown.js +70 -31
- package/dist/chat/ui/MermaidBlock.d.ts +3 -0
- package/dist/chat/ui/MermaidBlock.js +73 -0
- package/dist/chat/ui/MessageActions.js +12 -7
- package/dist/chat/ui/Pickers.js +6 -5
- package/dist/chat/ui/PromptComposer.js +4 -3
- package/dist/chat/ui/RowTime.d.ts +3 -0
- package/dist/chat/ui/RowTime.js +12 -0
- package/dist/chat/ui/RunSettings.js +5 -4
- package/dist/chat/ui/ShellCommand.d.ts +3 -0
- package/dist/chat/ui/ShellCommand.js +110 -0
- package/dist/chat/ui/SubagentInfo.js +4 -3
- package/dist/chat/ui/SubagentStopButton.js +4 -3
- package/dist/chat/ui/SubagentTimeline.js +4 -1
- package/dist/chat/ui/Timeline.js +70 -40
- package/dist/chat/ui/TimelineMenu.d.ts +2 -1
- package/dist/chat/ui/TimelineMenu.js +18 -8
- package/dist/chat/ui/UnifiedDiff.js +3 -2
- package/dist/chat/ui/VisualFrame.js +6 -7
- package/dist/chat/ui/code-theme.d.ts +2 -1
- package/dist/chat/ui/code-theme.js +4 -4
- package/dist/chat/ui/composer/ComposerControls.d.ts +27 -0
- package/dist/chat/ui/composer/ComposerControls.js +34 -0
- package/dist/chat/ui/composer/ComposerMenu.d.ts +4 -0
- package/dist/chat/ui/composer/ComposerMenu.js +46 -0
- package/dist/chat/ui/composer/DraftParts.d.ts +18 -0
- package/dist/chat/ui/composer/DraftParts.js +25 -0
- package/dist/chat/ui/composer/QueuedMessages.d.ts +10 -0
- package/dist/chat/ui/composer/QueuedMessages.js +20 -0
- package/dist/chat/ui/composer/key-handler.d.ts +20 -0
- package/dist/chat/ui/composer/key-handler.js +150 -0
- package/dist/chat/ui/composer/keys.d.ts +7 -2
- package/dist/chat/ui/composer/keys.js +19 -9
- package/dist/chat/ui/composer/placeholder.d.ts +9 -0
- package/dist/chat/ui/composer/placeholder.js +38 -0
- package/dist/chat/ui/composer/surface.d.ts +1 -0
- package/dist/chat/ui/composer/surface.js +44 -0
- package/dist/chat/ui/composer/use-chat-controls.d.ts +28 -0
- package/dist/chat/ui/composer/use-chat-controls.js +112 -0
- package/dist/chat/ui/composer/use-compaction-offer.d.ts +2 -0
- package/dist/chat/ui/composer/use-compaction-offer.js +23 -0
- package/dist/chat/ui/composer/use-composer-draft.d.ts +14 -0
- package/dist/chat/ui/composer/use-composer-draft.js +39 -0
- package/dist/chat/ui/composer/use-composer-menus.d.ts +52 -0
- package/dist/chat/ui/composer/use-composer-menus.js +232 -0
- package/dist/chat/ui/composer/use-composer-submit.d.ts +32 -0
- package/dist/chat/ui/composer/use-composer-submit.js +113 -0
- package/dist/chat/ui/composer/use-draft-files.d.ts +27 -0
- package/dist/chat/ui/composer/use-draft-files.js +111 -0
- package/dist/chat/ui/composer/use-notice.d.ts +6 -0
- package/dist/chat/ui/composer/use-notice.js +18 -0
- package/dist/chat/ui/composer/use-pending-requests.d.ts +2 -0
- package/dist/chat/ui/composer/use-pending-requests.js +22 -0
- package/dist/chat/ui/composer/use-prompt-history.d.ts +8 -0
- package/dist/chat/ui/composer/use-prompt-history.js +57 -0
- package/dist/chat/ui/composer/use-prompt-hold.d.ts +6 -0
- package/dist/chat/ui/composer/use-prompt-hold.js +48 -0
- package/dist/chat/ui/composer/use-take-back.d.ts +13 -0
- package/dist/chat/ui/composer/use-take-back.js +82 -0
- package/dist/chat/ui/diff/EditorEditDiff.js +4 -3
- package/dist/chat/ui/diff/LegacyDiffPool.js +3 -2
- package/dist/chat/ui/diff/LegacyEditDiff.js +3 -2
- package/dist/chat/ui/diff/LegacyUnifiedDiff.js +3 -2
- package/dist/chat/ui/diff/syntax-runtime.d.ts +2 -1
- package/dist/chat/ui/diff/syntax-runtime.js +9 -5
- package/dist/chat/ui/diff-syntax.d.ts +2 -2
- package/dist/chat/ui/diff-syntax.js +1 -2
- package/dist/chat/ui/diff-theme.js +10 -9
- package/dist/chat/ui/file-links.d.ts +1 -1
- package/dist/chat/ui/file-links.js +7 -5
- package/dist/chat/ui/highlighter.d.ts +27 -0
- package/dist/chat/ui/highlighter.js +151 -0
- package/dist/chat/ui/index.d.ts +67 -0
- package/dist/chat/ui/index.js +64 -0
- package/dist/chat/ui/intelligent-ui/UiReply.js +3 -2
- package/dist/chat/ui/intelligent-ui/renderers/content.js +3 -2
- package/dist/chat/ui/intelligent-ui/use-ui-links.js +2 -2
- package/dist/chat/ui/intelligent-ui/use-ui-queries.js +4 -3
- package/dist/chat/ui/markdown-blocks.d.ts +8 -0
- package/dist/chat/ui/markdown-blocks.js +260 -12
- package/dist/chat/ui/mermaid.d.ts +23 -0
- package/dist/chat/ui/mermaid.js +93 -0
- package/dist/chat/ui/rows/ForksRow.js +5 -3
- package/dist/chat/ui/rows/GeneratedImageRow.js +6 -4
- package/dist/chat/ui/rows/MessageRows.d.ts +4 -0
- package/dist/chat/ui/rows/MessageRows.js +36 -13
- package/dist/chat/ui/rows/Rows.js +3 -1
- package/dist/chat/ui/rows/SubagentRow.js +3 -2
- package/dist/chat/ui/rows/VisualRow.js +3 -2
- package/dist/chat/ui/rows/WorkRows.d.ts +6 -3
- package/dist/chat/ui/rows/WorkRows.js +57 -20
- package/dist/chat/ui/rows/WorkflowRow.js +3 -2
- package/dist/chat/ui/timestamp-format.d.ts +1 -0
- package/dist/chat/ui/timestamp-format.js +2 -0
- package/dist/chat/ui/use-diff-source-tokens.js +6 -3
- package/dist/chat/ui/visual-theme.js +3 -2
- package/dist/host.d.ts +9 -6
- package/dist/host.js +19 -8
- package/dist/index.d.ts +8 -0
- package/dist/index.js +9 -0
- package/dist/locales/en/agent-chat.d.ts +658 -0
- package/dist/locales/en/agent-chat.js +657 -0
- package/dist/locales/en/agent-prompts.d.ts +44 -0
- package/dist/locales/en/agent-prompts.js +43 -0
- package/dist/locales/en/agent-providers.d.ts +132 -0
- package/dist/locales/en/agent-providers.js +131 -0
- package/dist/locales/en/agent-usage.d.ts +132 -0
- package/dist/locales/en/agent-usage.js +131 -0
- package/dist/locales/nl/agent-chat.d.ts +658 -0
- package/dist/locales/nl/agent-chat.js +657 -0
- package/dist/locales/nl/agent-prompts.d.ts +44 -0
- package/dist/locales/nl/agent-prompts.js +43 -0
- package/dist/locales/nl/agent-providers.d.ts +132 -0
- package/dist/locales/nl/agent-providers.js +131 -0
- package/dist/locales/nl/agent-usage.d.ts +132 -0
- package/dist/locales/nl/agent-usage.js +131 -0
- package/dist/locales.js +9 -8
- package/dist/prompts/index.d.ts +11 -0
- package/dist/prompts/index.js +12 -0
- package/dist/prompts/logic/subjects.d.ts +2 -1
- package/dist/prompts/logic/subjects.js +6 -4
- package/dist/prompts/ui/ApprovalBody.js +6 -4
- package/dist/prompts/ui/PromptCard.js +5 -4
- package/dist/prompts/ui/PromptView.js +3 -2
- package/dist/prompts/ui/QuestionBody.js +3 -2
- package/dist/providers/AccountColors.js +2 -2
- package/dist/providers/AccountDetail.js +7 -6
- package/dist/providers/AccountVariables.js +3 -1
- package/dist/providers/AddAccountForm.js +3 -2
- package/dist/providers/ProvidersPane.js +4 -3
- package/dist/providers/account-actions.d.ts +4 -3
- package/dist/providers/account-actions.js +6 -7
- package/dist/providers/index.d.ts +16 -0
- package/dist/providers/index.js +17 -0
- package/dist/providers/provider-abilities.d.ts +2 -1
- package/dist/providers/provider-abilities.js +4 -0
- package/dist/state/chats.js +4 -2
- package/dist/state/index.d.ts +4 -0
- package/dist/state/index.js +5 -0
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.js +2 -0
- package/dist/{prompts/logic/prompts.fixtures.d.ts → testing/prompts.d.ts} +1 -1
- package/dist/theme.css +13 -3
- package/dist/usage/UsageBreakdown.js +3 -2
- package/dist/usage/UsageLimits.js +4 -3
- package/dist/usage/UsagePage.js +3 -2
- package/dist/usage/index.d.ts +15 -0
- package/dist/usage/index.js +15 -0
- package/package.json +53 -1031
- package/src/agents/AccountDot.tsx +3 -1
- package/src/agents/accounts.ts +6 -6
- package/src/chat/actions.ts +8 -5
- package/src/chat/bookmarks.ts +23 -14
- package/src/chat/chat-client.ts +8 -0
- package/src/chat/composer-send.ts +27 -0
- package/src/chat/forks.ts +27 -6
- package/src/chat/index.ts +98 -0
- package/src/chat/logic/embedded-code.ts +409 -0
- package/src/chat/logic/fork.ts +1 -0
- package/src/chat/logic/goal.ts +33 -0
- package/src/chat/logic/scrubber.ts +6 -5
- package/src/chat/logic/thought.ts +40 -0
- package/src/chat/logic/thread-cards.ts +2 -0
- package/src/chat/logic/timeline.ts +25 -1
- package/src/chat/logic/tool-catalog.ts +5 -1
- package/src/chat/logic/tools.ts +76 -0
- package/src/chat/preferences.ts +26 -3
- package/src/chat/reading-width.ts +39 -0
- package/src/chat/send-key.ts +38 -0
- package/src/chat/ui/BookmarkMarker.tsx +4 -2
- package/src/chat/ui/BookmarkSubmenu.tsx +4 -3
- package/src/chat/ui/ChatActivity.tsx +14 -10
- package/src/chat/ui/ChatReferenceChip.tsx +3 -4
- package/src/chat/ui/CodeBlock.tsx +33 -124
- package/src/chat/ui/Composer.tsx +212 -1358
- package/src/chat/ui/ComposerInput.tsx +5 -4
- package/src/chat/ui/EditDiff.tsx +3 -2
- package/src/chat/ui/GoalDock.tsx +104 -0
- package/src/chat/ui/LimitState.tsx +5 -3
- package/src/chat/ui/Markdown.tsx +113 -39
- package/src/chat/ui/MermaidBlock.tsx +119 -0
- package/src/chat/ui/MessageActions.tsx +13 -8
- package/src/chat/ui/Pickers.tsx +8 -7
- package/src/chat/ui/PromptComposer.tsx +4 -3
- package/src/chat/ui/RowTime.tsx +21 -0
- package/src/chat/ui/RunSettings.tsx +9 -4
- package/src/chat/ui/ShellCommand.tsx +134 -0
- package/src/chat/ui/SubagentInfo.tsx +4 -3
- package/src/chat/ui/SubagentStopButton.tsx +4 -3
- package/src/chat/ui/SubagentTimeline.tsx +5 -1
- package/src/chat/ui/Timeline.tsx +167 -105
- package/src/chat/ui/TimelineMenu.tsx +42 -7
- package/src/chat/ui/UnifiedDiff.tsx +3 -2
- package/src/chat/ui/VisualFrame.tsx +6 -7
- package/src/chat/ui/code-theme.ts +4 -4
- package/src/chat/ui/composer/ComposerControls.tsx +147 -0
- package/src/chat/ui/composer/ComposerMenu.tsx +138 -0
- package/src/chat/ui/composer/DraftParts.tsx +86 -0
- package/src/chat/ui/composer/QueuedMessages.tsx +64 -0
- package/src/chat/ui/composer/key-handler.ts +174 -0
- package/src/chat/ui/composer/keys.ts +32 -10
- package/src/chat/ui/composer/placeholder.ts +48 -0
- package/src/chat/ui/composer/surface.ts +45 -0
- package/src/chat/ui/composer/use-chat-controls.ts +134 -0
- package/src/chat/ui/composer/use-compaction-offer.ts +25 -0
- package/src/chat/ui/composer/use-composer-draft.ts +71 -0
- package/src/chat/ui/composer/use-composer-menus.ts +289 -0
- package/src/chat/ui/composer/use-composer-submit.ts +163 -0
- package/src/chat/ui/composer/use-draft-files.ts +135 -0
- package/src/chat/ui/composer/use-notice.ts +28 -0
- package/src/chat/ui/composer/use-pending-requests.ts +23 -0
- package/src/chat/ui/composer/use-prompt-history.ts +76 -0
- package/src/chat/ui/composer/use-prompt-hold.ts +58 -0
- package/src/chat/ui/composer/use-take-back.ts +91 -0
- package/src/chat/ui/diff/DiffFallbackBoundary.tsx +2 -2
- package/src/chat/ui/diff/EditorEditDiff.tsx +4 -3
- package/src/chat/ui/diff/LegacyDiffPool.tsx +3 -2
- package/src/chat/ui/diff/LegacyEditDiff.tsx +3 -2
- package/src/chat/ui/diff/LegacyUnifiedDiff.tsx +3 -2
- package/src/chat/ui/diff/syntax-runtime.ts +10 -5
- package/src/chat/ui/diff-syntax.ts +2 -2
- package/src/chat/ui/diff-theme.ts +10 -9
- package/src/chat/ui/file-links.ts +7 -5
- package/src/chat/ui/highlighter.ts +185 -0
- package/src/chat/ui/index.ts +109 -0
- package/src/chat/ui/intelligent-ui/UiReply.tsx +5 -4
- package/src/chat/ui/intelligent-ui/renderers/content.tsx +3 -2
- package/src/chat/ui/intelligent-ui/use-ui-links.ts +2 -2
- package/src/chat/ui/intelligent-ui/use-ui-queries.ts +4 -3
- package/src/chat/ui/markdown-blocks.ts +300 -12
- package/src/chat/ui/mermaid.ts +118 -0
- package/src/chat/ui/rows/ForksRow.tsx +5 -3
- package/src/chat/ui/rows/GeneratedImageRow.tsx +6 -4
- package/src/chat/ui/rows/MessageRows.tsx +73 -18
- package/src/chat/ui/rows/Rows.tsx +14 -1
- package/src/chat/ui/rows/SubagentRow.tsx +3 -2
- package/src/chat/ui/rows/VisualRow.tsx +3 -2
- package/src/chat/ui/rows/WorkRows.tsx +148 -47
- package/src/chat/ui/rows/WorkflowRow.tsx +3 -2
- package/src/chat/ui/timestamp-format.ts +2 -0
- package/src/chat/ui/use-diff-source-tokens.ts +10 -4
- package/src/chat/ui/visual-theme.ts +3 -2
- package/src/host.ts +31 -15
- package/src/index.ts +49 -0
- package/src/locales/en/agent-chat.ts +657 -0
- package/src/locales/en/agent-prompts.ts +43 -0
- package/src/locales/en/agent-providers.ts +131 -0
- package/src/locales/en/agent-usage.ts +131 -0
- package/src/locales/nl/agent-chat.ts +657 -0
- package/src/locales/nl/agent-prompts.ts +43 -0
- package/src/locales/nl/agent-providers.ts +131 -0
- package/src/locales/nl/agent-usage.ts +132 -0
- package/src/locales.ts +9 -8
- package/src/prompts/index.ts +35 -0
- package/src/prompts/logic/subjects.ts +12 -4
- package/src/prompts/ui/ApprovalBody.tsx +6 -4
- package/src/prompts/ui/PromptCard.tsx +11 -4
- package/src/prompts/ui/PromptView.tsx +3 -2
- package/src/prompts/ui/QuestionBody.tsx +3 -2
- package/src/providers/AccountColors.tsx +2 -2
- package/src/providers/AccountDetail.tsx +13 -7
- package/src/providers/AccountVariables.tsx +3 -1
- package/src/providers/AddAccountForm.tsx +3 -2
- package/src/providers/ProvidersPane.tsx +4 -3
- package/src/providers/account-actions.ts +7 -7
- package/src/providers/index.ts +17 -0
- package/src/providers/provider-abilities.ts +6 -1
- package/src/state/chats.ts +4 -2
- package/src/state/index.ts +39 -0
- package/src/testing/index.ts +2 -0
- package/src/{prompts/logic/prompts.fixtures.ts → testing/prompts.ts} +1 -1
- package/src/theme.css +13 -3
- package/src/usage/UsageBreakdown.tsx +3 -2
- package/src/usage/UsageLimits.tsx +4 -3
- package/src/usage/UsagePage.tsx +3 -2
- package/src/usage/index.ts +16 -0
- package/dist/locales/en/agent-chat.json +0 -597
- package/dist/locales/en/agent-prompts.json +0 -43
- package/dist/locales/en/agent-providers.json +0 -131
- package/dist/locales/en/agent-usage.json +0 -131
- package/dist/locales/nl/agent-chat.json +0 -597
- package/dist/locales/nl/agent-prompts.json +0 -43
- package/dist/locales/nl/agent-providers.json +0 -131
- package/dist/locales/nl/agent-usage.json +0 -131
- package/src/locales/en/agent-chat.json +0 -597
- package/src/locales/en/agent-prompts.json +0 -43
- package/src/locales/en/agent-providers.json +0 -131
- package/src/locales/en/agent-usage.json +0 -131
- package/src/locales/nl/agent-chat.json +0 -597
- package/src/locales/nl/agent-prompts.json +0 -43
- package/src/locales/nl/agent-providers.json +0 -131
- package/src/locales/nl/agent-usage.json +0 -131
- /package/dist/{prompts/logic/prompts.fixtures.js → testing/prompts.js} +0 -0
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import type { SyntaxNode, Tree } from '@lezer/common';
|
|
2
|
+
import { modSends, type ChatSendKey } from '../../send-key';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
/* `send-alternate` sends with the delivery a running turn does not get by default; `send-and-new` also opens a new chat once it went. */
|
|
5
|
+
export type EnterAction = 'send' | 'send-alternate' | 'send-and-new' | 'newline' | 'continue-list' | 'leave-list';
|
|
4
6
|
|
|
5
7
|
export interface EnterKeys {
|
|
6
8
|
shift: boolean;
|
|
7
9
|
/* Cmd on macOS, Ctrl elsewhere. */
|
|
8
10
|
mod: boolean;
|
|
11
|
+
/* Option on macOS. */
|
|
12
|
+
alt?: boolean;
|
|
9
13
|
}
|
|
10
14
|
|
|
11
15
|
export interface ListItem {
|
|
@@ -23,6 +27,12 @@ export interface EnterContext {
|
|
|
23
27
|
list: ListItem | null;
|
|
24
28
|
/* The caret's offset in its line. */
|
|
25
29
|
column: number;
|
|
30
|
+
/* Which key sends; `enter` when left out. */
|
|
31
|
+
sendKey?: ChatSendKey;
|
|
32
|
+
/* The message runs over more than one line, where `mod-enter-multiline` lets Enter add a line. */
|
|
33
|
+
multiline?: boolean;
|
|
34
|
+
/* The host opens a new chat after a send, which Mod+Alt+Enter asks for. */
|
|
35
|
+
startsNewChat?: boolean;
|
|
26
36
|
}
|
|
27
37
|
|
|
28
38
|
const LIST_ITEM = /^([ \t]*)(?:([-*+])|(\d{1,9})([.)]))([ \t]+)(\[[ xX]\](?:[ \t]+|$))?/;
|
|
@@ -41,23 +51,35 @@ export function listItemAt(line: string): ListItem | null {
|
|
|
41
51
|
/*
|
|
42
52
|
* Enter sends, except where whoever types is still writing: inside a fence nobody has closed yet
|
|
43
53
|
* it adds a line, and in a list it starts the next item, or leaves the list from an empty one, so
|
|
44
|
-
* a second Enter breaks out. Shift adds a plain line and Mod sends from anywhere.
|
|
54
|
+
* a second Enter breaks out. Shift adds a plain line and Mod sends from anywhere. Where the send key
|
|
55
|
+
* is Mod+Enter, Enter adds a line instead of sending. Alt sends the other way (queue or steer), and so
|
|
56
|
+
* does Mod+Shift+Enter where Mod+Enter is the send key; Mod+Alt+Enter is the send that opens a new chat.
|
|
45
57
|
*/
|
|
46
|
-
export function enterAction(
|
|
58
|
+
export function enterAction(
|
|
59
|
+
keys: EnterKeys,
|
|
60
|
+
{ inOpenFence, list, column, sendKey = 'enter', multiline = false, startsNewChat = false }: EnterContext
|
|
61
|
+
): EnterAction {
|
|
62
|
+
const modOnly = modSends(sendKey, multiline);
|
|
47
63
|
if (keys.mod) {
|
|
48
|
-
|
|
64
|
+
if (keys.alt && startsNewChat) {
|
|
65
|
+
return 'send-and-new';
|
|
66
|
+
}
|
|
67
|
+
return keys.alt || (modOnly && keys.shift) ? 'send-alternate' : 'send';
|
|
49
68
|
}
|
|
50
69
|
if (keys.shift || inOpenFence) {
|
|
51
70
|
return 'newline';
|
|
52
71
|
}
|
|
53
|
-
if (list
|
|
54
|
-
|
|
72
|
+
if (list !== null) {
|
|
73
|
+
// A caret in front of the marker moves the item down rather than splitting its marker.
|
|
74
|
+
if (column < list.prefix.length) {
|
|
75
|
+
return 'newline';
|
|
76
|
+
}
|
|
77
|
+
return list.empty ? 'leave-list' : 'continue-list';
|
|
55
78
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
return 'newline';
|
|
79
|
+
if (keys.alt) {
|
|
80
|
+
return 'send-alternate';
|
|
59
81
|
}
|
|
60
|
-
return
|
|
82
|
+
return modOnly ? 'newline' : 'send';
|
|
61
83
|
}
|
|
62
84
|
|
|
63
85
|
/* The innermost fenced code block around `pos`, if any. */
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { useTranslation } from 'react-i18next';
|
|
3
|
+
import { useChatHost } from '../../../host';
|
|
4
|
+
import { useChatScope } from '../../../scope';
|
|
5
|
+
|
|
6
|
+
/* The empty box names its sigils as key caps, so they read as keys to press rather than as punctuation. */
|
|
7
|
+
function hintedPlaceholder(lead: string, joiner: string, hints: ReadonlyArray<{ key: string; label: string }>): HTMLElement {
|
|
8
|
+
const root = document.createElement('span');
|
|
9
|
+
root.className = 'composer-hints';
|
|
10
|
+
const extra = document.createElement('span');
|
|
11
|
+
extra.className = 'composer-hints-extra';
|
|
12
|
+
extra.append(joiner);
|
|
13
|
+
for (const hint of hints) {
|
|
14
|
+
const cap = document.createElement('kbd');
|
|
15
|
+
cap.textContent = hint.key;
|
|
16
|
+
extra.append(cap, hint.label);
|
|
17
|
+
}
|
|
18
|
+
root.append(lead, extra);
|
|
19
|
+
return root;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface PlaceholderInput {
|
|
23
|
+
chatId: string;
|
|
24
|
+
disabled: boolean;
|
|
25
|
+
readOnly: boolean;
|
|
26
|
+
mentionable: boolean;
|
|
27
|
+
hasSkills: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* What the empty box says: why nothing can be written, or the host's words and the keys that open a picker. */
|
|
31
|
+
export function useHintedPlaceholder({ chatId, disabled, readOnly, mentionable, hasSkills }: PlaceholderInput): string | HTMLElement {
|
|
32
|
+
const { t } = useTranslation('agent-chat');
|
|
33
|
+
const scope = useChatScope();
|
|
34
|
+
const lead = useChatHost().useComposerPlaceholder(scope.id, chatId);
|
|
35
|
+
return useMemo(() => {
|
|
36
|
+
if (disabled) {
|
|
37
|
+
return t('composer.placeholder.disconnected');
|
|
38
|
+
}
|
|
39
|
+
if (readOnly) {
|
|
40
|
+
return t('composer.placeholder.readOnly');
|
|
41
|
+
}
|
|
42
|
+
return hintedPlaceholder(lead ?? t('composer.placeholder.lead'), t('composer.placeholder.joiner'), [
|
|
43
|
+
{ key: '/', label: t('composer.placeholder.commands') },
|
|
44
|
+
...(mentionable ? [{ key: '@', label: t('composer.placeholder.files') }] : []),
|
|
45
|
+
...(hasSkills ? [{ key: '$', label: t('composer.placeholder.skills') }] : [])
|
|
46
|
+
]);
|
|
47
|
+
}, [disabled, readOnly, lead, mentionable, hasSkills, t]);
|
|
48
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/* Anything with an action of its own; `data-composer-action` marks one a role cannot name, such as a control of the host's. */
|
|
2
|
+
const ACTIONS = [
|
|
3
|
+
'a',
|
|
4
|
+
'button',
|
|
5
|
+
'input',
|
|
6
|
+
'select',
|
|
7
|
+
'textarea',
|
|
8
|
+
'label',
|
|
9
|
+
'summary',
|
|
10
|
+
'[contenteditable]:not([contenteditable="false"])',
|
|
11
|
+
'[tabindex]:not([tabindex="-1"])',
|
|
12
|
+
'[role="button"]',
|
|
13
|
+
'[role="link"]',
|
|
14
|
+
'[role="menuitem"]',
|
|
15
|
+
'[role="menuitemcheckbox"]',
|
|
16
|
+
'[role="menuitemradio"]',
|
|
17
|
+
'[role="option"]',
|
|
18
|
+
'[role="listbox"]',
|
|
19
|
+
'[role="checkbox"]',
|
|
20
|
+
'[role="radio"]',
|
|
21
|
+
'[role="switch"]',
|
|
22
|
+
'[role="tab"]',
|
|
23
|
+
'[role="slider"]',
|
|
24
|
+
'[role="combobox"]',
|
|
25
|
+
'[data-composer-action]'
|
|
26
|
+
].join(', ');
|
|
27
|
+
|
|
28
|
+
/*
|
|
29
|
+
* Where a pointer is on the composer: in the text field, on an action, or on the space around them,
|
|
30
|
+
* which stands in for the text field. A target outside the surface is an action, as an event from a
|
|
31
|
+
* popup portaled out of it still reaches the surface through React.
|
|
32
|
+
*/
|
|
33
|
+
export function surfacePartOf(target: EventTarget | null, surface: Element): 'input' | 'action' | 'surface' {
|
|
34
|
+
// Not `instanceof Element`, which fails for an element of another window.
|
|
35
|
+
const element = target as Element | null;
|
|
36
|
+
if (typeof element?.closest !== 'function' || !surface.contains(element)) {
|
|
37
|
+
return 'action';
|
|
38
|
+
}
|
|
39
|
+
const input = element.closest('.cm-editor');
|
|
40
|
+
if (input !== null && surface.contains(input)) {
|
|
41
|
+
return 'input';
|
|
42
|
+
}
|
|
43
|
+
const action = element.closest(ACTIONS);
|
|
44
|
+
return action !== null && surface.contains(action) ? 'action' : 'surface';
|
|
45
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { useRef, useState } from 'react';
|
|
2
|
+
import { useTranslation } from 'react-i18next';
|
|
3
|
+
import type { AgentKind, ChatInfo, ModelSelection, RuntimeMode } from '@adecore/agent-contracts';
|
|
4
|
+
import { useChatHost } from '../../../host';
|
|
5
|
+
import { useChatScope } from '../../../scope';
|
|
6
|
+
import { errorCode } from '../../../transport';
|
|
7
|
+
import { useChatActions } from '../../actions';
|
|
8
|
+
import { rememberChatAccount, rememberChatPreferences, rememberChatSelection } from '../../preferences';
|
|
9
|
+
import { composerStopOf } from '../../subagent-list';
|
|
10
|
+
import type { ComposerNotice } from './use-notice';
|
|
11
|
+
|
|
12
|
+
interface ControlsInput {
|
|
13
|
+
chatId: string;
|
|
14
|
+
info: ChatInfo;
|
|
15
|
+
notice: ComposerNotice;
|
|
16
|
+
onRetarget(provider: AgentKind, selection: ModelSelection): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/* What the composer does to the chat rather than to its draft: its settings, a stop, a clear and a compaction. */
|
|
20
|
+
export function useChatControls({ chatId, info, notice: { setNotice, showError }, onRetarget }: ControlsInput) {
|
|
21
|
+
const { t } = useTranslation('agent-chat');
|
|
22
|
+
const host = useChatHost();
|
|
23
|
+
const scope = useChatScope();
|
|
24
|
+
const actions = useChatActions();
|
|
25
|
+
const configuring = useRef(false);
|
|
26
|
+
const [configurationPending, setConfigurationPending] = useState(false);
|
|
27
|
+
const [modelPickerOpen, setModelPickerOpen] = useState(false);
|
|
28
|
+
const [confirmClear, setConfirmClear] = useState(false);
|
|
29
|
+
|
|
30
|
+
/* One configuration at a time; a second pick while one is on its way is dropped. */
|
|
31
|
+
const runConfiguration = (work: () => Promise<void>): void => {
|
|
32
|
+
if (configuring.current) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
configuring.current = true;
|
|
36
|
+
setConfigurationPending(true);
|
|
37
|
+
void work()
|
|
38
|
+
.catch(showError)
|
|
39
|
+
.finally(() => {
|
|
40
|
+
configuring.current = false;
|
|
41
|
+
setConfigurationPending(false);
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const configure = (patch: { selection?: ModelSelection; runtimeMode?: RuntimeMode; account?: string }): void => {
|
|
46
|
+
runConfiguration(() =>
|
|
47
|
+
actions.configure(chatId, patch).then(() => {
|
|
48
|
+
if (patch.selection) {
|
|
49
|
+
rememberChatSelection(info.provider, patch.selection);
|
|
50
|
+
}
|
|
51
|
+
if (patch.runtimeMode) {
|
|
52
|
+
rememberChatPreferences({ runtimeMode: patch.runtimeMode });
|
|
53
|
+
}
|
|
54
|
+
if (patch.account) {
|
|
55
|
+
rememberChatAccount(scope.id, info.provider, patch.account);
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/* A model of another CLI re-points the whole chat; one of this CLI's own is a configure. */
|
|
62
|
+
const chooseModel = (provider: AgentKind, slug: string): void => {
|
|
63
|
+
const selection: ModelSelection = { model: slug, options: {} };
|
|
64
|
+
if (provider !== info.provider) {
|
|
65
|
+
runConfiguration(() => onRetarget(provider, selection).then(() => rememberChatSelection(provider, selection)));
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
configure({ selection });
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const stop = (shiftKey: boolean): void => {
|
|
72
|
+
if (composerStopOf(shiftKey) === 'turn') {
|
|
73
|
+
void actions.stopTurn(chatId, false).catch(showError);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
host.confirm.stopSubagents(scope.id, chatId, () => void actions.stopTurn(chatId, true).catch(showError));
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/* The host decides whether a turn is in the way; only its refusal asks the person first. */
|
|
80
|
+
const clearThread = async (): Promise<void> => {
|
|
81
|
+
try {
|
|
82
|
+
await actions.clear(chatId, false);
|
|
83
|
+
} catch (e) {
|
|
84
|
+
if (errorCode(e) === 'chat-busy') {
|
|
85
|
+
setConfirmClear(true);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
setNotice(t('composer.notice.clearFailed'));
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const forceClearThread = async (): Promise<void> => {
|
|
93
|
+
await actions.clear(chatId, true);
|
|
94
|
+
setConfirmClear(false);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const compact = (): void => {
|
|
98
|
+
void actions.compact(chatId).catch(() => setNotice(t('composer.notice.compactFailed')));
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
/* Runs one of the composer's own commands; false for a name it does not handle. */
|
|
102
|
+
const runCommand = (name: string): boolean => {
|
|
103
|
+
switch (name) {
|
|
104
|
+
case 'model':
|
|
105
|
+
setModelPickerOpen(true);
|
|
106
|
+
return true;
|
|
107
|
+
case 'compact':
|
|
108
|
+
void actions.compact(chatId).catch(() => undefined);
|
|
109
|
+
return true;
|
|
110
|
+
case 'clear':
|
|
111
|
+
void clearThread();
|
|
112
|
+
return true;
|
|
113
|
+
default:
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
configurationPending,
|
|
120
|
+
configure,
|
|
121
|
+
chooseModel,
|
|
122
|
+
chooseAccount: (account: string): void => configure({ account }),
|
|
123
|
+
stop,
|
|
124
|
+
compact,
|
|
125
|
+
runCommand,
|
|
126
|
+
modelPickerOpen,
|
|
127
|
+
setModelPickerOpen,
|
|
128
|
+
confirmClear,
|
|
129
|
+
cancelClear: (): void => setConfirmClear(false),
|
|
130
|
+
forceClearThread
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export type ChatControls = ReturnType<typeof useChatControls>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ChatInfo, ChatItem, ProviderCapabilities } from '@adecore/agent-contracts';
|
|
2
|
+
import { useNow } from '@adecore/ui';
|
|
3
|
+
import { useChatRow } from '../../../state/chats';
|
|
4
|
+
import { RESUME_COMPACTION_TOKENS, resumeCompactionOffer } from '../../logic/resume-compaction';
|
|
5
|
+
import { useResumeCompactionDismissal } from '../../resume-compaction-dismissals';
|
|
6
|
+
|
|
7
|
+
/* The offer to fold a long context before a chat that sat idle goes on, or null when there is none. */
|
|
8
|
+
export function useCompactionOffer(chatId: string, info: ChatInfo, compaction: ProviderCapabilities['compaction'] | undefined) {
|
|
9
|
+
const order = useChatRow(chatId, (row) => row?.order);
|
|
10
|
+
const items = useChatRow(chatId, (row) => row?.structure);
|
|
11
|
+
const dismissedTurnId = useResumeCompactionDismissal(chatId);
|
|
12
|
+
// The cheap half of the offer, so a chat that can never make one keeps no timer.
|
|
13
|
+
const couldOffer = compaction !== undefined && compaction !== 'none' && info.usage.contextTokens >= RESUME_COMPACTION_TOKENS;
|
|
14
|
+
const now = useNow(60_000, couldOffer);
|
|
15
|
+
if (!couldOffer) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
return resumeCompactionOffer({
|
|
19
|
+
info,
|
|
20
|
+
compaction,
|
|
21
|
+
items: (order ?? []).map((id) => items?.[id]).filter((item): item is ChatItem => item !== undefined),
|
|
22
|
+
dismissedTurnId,
|
|
23
|
+
now
|
|
24
|
+
});
|
|
25
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { useContext, useEffect, useRef, useState, type Dispatch, type RefObject, type SetStateAction } from 'react';
|
|
2
|
+
import { EMPTY_DRAFT, joinDraftText, readDraft, takeDraftOffers, writeDraft, type ChatDraft } from '../../drafts';
|
|
3
|
+
import type { ComposerInputHandle } from '../ComposerInput';
|
|
4
|
+
import { QuoteTakerContext } from '../quote-selection';
|
|
5
|
+
|
|
6
|
+
export interface ComposerDraft {
|
|
7
|
+
draft: ChatDraft;
|
|
8
|
+
setDraft: Dispatch<SetStateAction<ChatDraft>>;
|
|
9
|
+
/* Taking a queued message back waits on the machine, and what was typed meanwhile is what it merges with. */
|
|
10
|
+
latest: RefObject<ChatDraft>;
|
|
11
|
+
/* The mentions and skills default to the draft's own as last rendered. */
|
|
12
|
+
setText(next: string, mentions?: string[], skills?: string[]): void;
|
|
13
|
+
clear(): void;
|
|
14
|
+
removeQuote(): void;
|
|
15
|
+
removeChat(id: string): void;
|
|
16
|
+
removeAttachment(index: number): void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/* The chat's unsent prompt, kept in storage as it changes and open to text and quotes handed in from outside. */
|
|
20
|
+
export function useComposerDraft(chatId: string, inputRef: RefObject<ComposerInputHandle | null>): ComposerDraft {
|
|
21
|
+
const [draft, setDraft] = useState<ChatDraft>(() => readDraft(chatId));
|
|
22
|
+
const latest = useRef(draft);
|
|
23
|
+
const registerQuoteTaker = useContext(QuoteTakerContext);
|
|
24
|
+
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
latest.current = draft;
|
|
27
|
+
writeDraft(chatId, draft);
|
|
28
|
+
}, [chatId, draft]);
|
|
29
|
+
|
|
30
|
+
useEffect(
|
|
31
|
+
() =>
|
|
32
|
+
takeDraftOffers(chatId, (offered) => {
|
|
33
|
+
setDraft((current) => ({ ...current, text: joinDraftText(current.text, offered) }));
|
|
34
|
+
inputRef.current?.focus();
|
|
35
|
+
}),
|
|
36
|
+
[chatId, inputRef]
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
useEffect(
|
|
40
|
+
() =>
|
|
41
|
+
registerQuoteTaker?.((selected, itemId) => {
|
|
42
|
+
setDraft((current) => ({ ...current, quote: selected, quoteSource: itemId }));
|
|
43
|
+
inputRef.current?.focus();
|
|
44
|
+
}),
|
|
45
|
+
[registerQuoteTaker, inputRef]
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
const setText = (next: string, mentions = draft.mentions, chosen = draft.skills): void => {
|
|
49
|
+
setDraft((current) => ({ ...current, text: next, mentions, skills: chosen }));
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const clear = (): void => {
|
|
53
|
+
setDraft(EMPTY_DRAFT);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const removeQuote = (): void => {
|
|
57
|
+
setDraft((current) => ({ ...current, quote: '', quoteSource: null }));
|
|
58
|
+
inputRef.current?.focus();
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const removeChat = (id: string): void => {
|
|
62
|
+
setDraft((current) => ({ ...current, chats: current.chats.filter((entry) => entry !== id) }));
|
|
63
|
+
inputRef.current?.focus();
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const removeAttachment = (index: number): void => {
|
|
67
|
+
setDraft((current) => ({ ...current, attachments: current.attachments.filter((_, i) => i !== index) }));
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
return { draft, setDraft, latest, setText, clear, removeQuote, removeChat, removeAttachment };
|
|
71
|
+
}
|