@adecore/agents-react 0.23.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +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 +117 -906
- 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/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 +162 -1324
- 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/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,5 +1,4 @@
|
|
|
1
1
|
import i18next from 'i18next';
|
|
2
|
-
import { chatHost } from '../../host.js';
|
|
3
2
|
import { isBlockingPrompt } from './prompts.js';
|
|
4
3
|
/* Unique across the chats of a surface and the app's own prompts, and stable while the prompt waits. */
|
|
5
4
|
export function promptIdOf(subject) {
|
|
@@ -41,10 +40,13 @@ export function approvalButtons(subject, reason) {
|
|
|
41
40
|
{ id: 'allow', label: i18next.t('agent-prompts:approval.allow'), primary: true, action: { kind: 'approve', decision: 'allow' } }
|
|
42
41
|
];
|
|
43
42
|
}
|
|
44
|
-
/*
|
|
45
|
-
|
|
43
|
+
/*
|
|
44
|
+
* Sends a card's action as the request its subject is answered with, or to `host` for a prompt it raised.
|
|
45
|
+
* A refusal comes back as an error for the card to show.
|
|
46
|
+
*/
|
|
47
|
+
export async function answerPrompt(subject, action, chat, host) {
|
|
46
48
|
if (subject.kind === 'host') {
|
|
47
|
-
return
|
|
49
|
+
return host.prompts.answer(subject.prompt, action);
|
|
48
50
|
}
|
|
49
51
|
if (chat === null) {
|
|
50
52
|
throw new Error(i18next.t('agent-prompts:error.notConnected'));
|
|
@@ -3,7 +3,7 @@ import { useState } from 'react';
|
|
|
3
3
|
import clsx from 'clsx';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
5
5
|
import { approvalChanges, fileChanges } from '../../chat/logic/tools.js';
|
|
6
|
-
import {
|
|
6
|
+
import { useChatHost } from '../../host.js';
|
|
7
7
|
import { ApprovalReview } from '../../chat/ui/diff/ApprovalReview.js';
|
|
8
8
|
import { reviewEntries } from '../../chat/ui/diff/review-plan.js';
|
|
9
9
|
import { isPrimaryKey } from '../logic/keys.js';
|
|
@@ -13,23 +13,25 @@ export function CommandBox({ command, cwd }) {
|
|
|
13
13
|
return (_jsxs(TextMenu, { className: "rounded-xl bg-surface-sunken p-3", children: [cwd !== undefined && _jsx("p", { className: "mb-2 break-all font-mono text-xs text-text-muted select-text", children: cwd }), _jsx("pre", { className: "whitespace-pre-wrap break-words font-mono text-code text-text select-text", children: command })] }));
|
|
14
14
|
}
|
|
15
15
|
function ApprovalDetails({ item }) {
|
|
16
|
+
const host = useChatHost();
|
|
16
17
|
const { t } = useTranslation('agent-prompts');
|
|
17
18
|
const [expanded, setExpanded] = useState(false);
|
|
18
19
|
const patches = approvalChanges(item.input);
|
|
19
20
|
const edits = patches.length ? [] : fileChanges(item.toolName, item.input);
|
|
20
21
|
const entries = reviewEntries(patches, edits);
|
|
21
|
-
const editorPreview =
|
|
22
|
+
const editorPreview = host.code.editor !== undefined;
|
|
22
23
|
const maxHeight = expanded ? 480 : 176;
|
|
23
24
|
const input = typeof item.input === 'object' && item.input !== null ? item.input : {};
|
|
24
25
|
return (_jsxs(_Fragment, { children: [item.description && _jsx("p", { className: "text-sm text-text-muted", children: item.description }), patches.length + edits.length > 1 && (_jsx("p", { className: "text-xs text-text-muted", children: t('approval.allChanges', { count: patches.length + edits.length }) })), patches.length + edits.length > 0 ? (_jsxs("div", { className: "overflow-hidden rounded-xl bg-surface-sunken", children: [_jsx("div", { className: clsx(editorPreview ? 'overflow-hidden' : 'overflow-auto', !editorPreview && !expanded && 'max-h-44'), children: _jsx(ApprovalReview, { entries: entries, maxHeight: maxHeight }, item.requestId) }), _jsx("div", { className: "flex items-center border-t border-border p-1", children: _jsx(Button, { size: "sm", "aria-expanded": expanded, onClick: () => setExpanded(!expanded), children: expanded ? t('approval.collapseDiff') : t('approval.viewDiff') }) })] })) : typeof input.command === 'string' ? (_jsx(CommandBox, { command: input.command, cwd: typeof input.cwd === 'string' ? input.cwd : undefined })) : (_jsxs("details", { children: [_jsx("summary", { className: "flex h-7 cursor-pointer items-center text-xs text-text-muted", children: t('approval.details') }), _jsx(TextMenu, { children: _jsx("pre", { className: "max-h-64 overflow-auto whitespace-pre-wrap break-words rounded-xl bg-surface-sunken p-3 font-mono text-code text-text select-text", children: JSON.stringify(item.input, null, 2) }) })] }))] }));
|
|
25
26
|
}
|
|
26
27
|
/* A chat's permission request: the diff, the command or the raw input, and the reason a Deny may carry. */
|
|
27
28
|
export function ApprovalBody({ item, draft, onDraft, denyReason, locked }) {
|
|
29
|
+
const host = useChatHost();
|
|
28
30
|
const { t } = useTranslation('agent-prompts');
|
|
29
|
-
const AnswerField =
|
|
31
|
+
const AnswerField = host.dictation.Textarea;
|
|
30
32
|
return (_jsxs(_Fragment, { children: [_jsx(ApprovalDetails, { item: item }), denyReason && draft.showReason && (_jsx(AnswerField, { className: "field min-h-16 text-sm", autoFocus: true, "aria-label": t('approval.reasonLabel'), placeholder: t('approval.reasonPlaceholder'), disabled: locked, value: draft.reason, onChange: (e) => onDraft({ ...draft, reason: e.target.value }), onKeyDown: (e) => {
|
|
31
33
|
// Mod+Enter presses Allow everywhere else in the card, which is the opposite of what a reason for declining is typed for.
|
|
32
|
-
if (isPrimaryKey(e.nativeEvent,
|
|
34
|
+
if (isPrimaryKey(e.nativeEvent, host.isApplePlatform())) {
|
|
33
35
|
e.preventDefault();
|
|
34
36
|
}
|
|
35
37
|
} }))] }));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useTranslation } from 'react-i18next';
|
|
3
3
|
import { Hand, MessageCircleQuestionMark } from 'lucide-react';
|
|
4
|
-
import {
|
|
4
|
+
import { useChatHost } from '../../host.js';
|
|
5
5
|
import { headingKey, isPrimaryKey, staysInCard, stepIndex, toolbarKey } from '../logic/keys.js';
|
|
6
6
|
import { Icon } from '@adecore/ui';
|
|
7
7
|
/* The raised glass a chat's composer is made of, for a card that stands on its own over a canvas. */
|
|
@@ -11,11 +11,11 @@ const ICONS = { approval: Hand, question: MessageCircleQuestionMark, waiting: Me
|
|
|
11
11
|
* The keys every card shares: Mod+Enter, entering from the heading and the action row. The body handles
|
|
12
12
|
* its own keys first and says so with `preventDefault`.
|
|
13
13
|
*/
|
|
14
|
-
function onCardKeyDown(event) {
|
|
14
|
+
function onCardKeyDown(event, apple) {
|
|
15
15
|
const card = event.currentTarget;
|
|
16
16
|
const target = event.target instanceof HTMLElement ? event.target : null;
|
|
17
17
|
if (!event.defaultPrevented) {
|
|
18
|
-
if (isPrimaryKey(event.nativeEvent,
|
|
18
|
+
if (isPrimaryKey(event.nativeEvent, apple)) {
|
|
19
19
|
event.preventDefault();
|
|
20
20
|
// A click on the button itself, so a disabled Next or Answer stays as disabled as it looks.
|
|
21
21
|
card.querySelector('[data-prompt-primary]:not(:disabled)')?.click();
|
|
@@ -42,7 +42,8 @@ function onCardKeyDown(event) {
|
|
|
42
42
|
/* What every prompt looks like, whatever asked it: in a chat's composer and in a canvas's stack. */
|
|
43
43
|
export function PromptCard({ kind, heading, meta, top, actions, busy, notice, error, children }) {
|
|
44
44
|
const { t } = useTranslation('agent-prompts');
|
|
45
|
-
const
|
|
45
|
+
const { isApplePlatform } = useChatHost();
|
|
46
|
+
const card = (_jsxs("div", { className: "prompt-card flex min-h-0 flex-col gap-2 p-3", role: "group", "aria-label": t(`card.${kind}`), "aria-busy": busy, onKeyDown: (event) => onCardKeyDown(event, isApplePlatform()), children: [_jsx("div", { className: "-m-1.5 max-h-[min(50dvh,480px)] overflow-auto overscroll-contain p-1.5", children: _jsxs("div", { className: "flex flex-col gap-2", children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Icon, { icon: ICONS[kind], size: 16, className: "mt-[3px] shrink-0 text-status-needs-you" }), _jsx("h3", { tabIndex: -1, className: "prompt-heading min-w-0 break-words text-sm font-semibold text-text outline-offset-4", children: heading })] }), meta && _jsx("div", { className: "flex flex-wrap gap-x-3 gap-y-1 text-xs text-text-muted", children: meta }), children, notice && _jsx("p", { className: "text-xs text-text-muted", children: notice }), error && (_jsx("p", { role: "alert", className: "text-xs text-status-error", children: error }))] }) }), _jsx("div", { role: "toolbar", "aria-label": t('toolbar'), className: "flex flex-wrap items-center gap-1.5", children: actions })] }));
|
|
46
47
|
if (top === undefined) {
|
|
47
48
|
return card;
|
|
48
49
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useTranslation } from 'react-i18next';
|
|
3
3
|
import { toolSummary } from '../../chat/logic/tools.js';
|
|
4
|
-
import {
|
|
4
|
+
import { useChatHost } from '../../host.js';
|
|
5
5
|
import { answerValue, promptAnswers, questionAnswer } from '../logic/prompts.js';
|
|
6
6
|
import { approvalButtons } from '../logic/subjects.js';
|
|
7
7
|
import { ApprovalBody } from './ApprovalBody.js';
|
|
@@ -12,11 +12,12 @@ import { QuestionBody } from './QuestionBody.js';
|
|
|
12
12
|
export function PromptView(props) {
|
|
13
13
|
const { subject, draft, onDraft, onAction, more, hasDraft, denyReason, disabled, sending, error, top } = props;
|
|
14
14
|
const { t } = useTranslation('agent-prompts');
|
|
15
|
+
const { prompts } = useChatHost();
|
|
15
16
|
const locked = sending || disabled;
|
|
16
17
|
const notice = disabled ? t('error.notConnected') : null;
|
|
17
18
|
const buttons = approvalButtons(subject, draft.reason).map(({ action, ...button }) => ({ ...button, onPress: () => onAction(action) }));
|
|
18
19
|
if (subject.kind === 'host') {
|
|
19
|
-
return
|
|
20
|
+
return prompts.render(subject.prompt, props);
|
|
20
21
|
}
|
|
21
22
|
const { item } = subject;
|
|
22
23
|
const question = item.kind === 'question' ? item.questions[Math.min(draft.index, item.questions.length - 1)] : null;
|
|
@@ -6,11 +6,12 @@ import { Circle, CircleCheck, Square } from 'lucide-react';
|
|
|
6
6
|
import { answerFieldKey, choiceKey, stepIndex } from '../logic/keys.js';
|
|
7
7
|
import { pickPromptChoice } from '../logic/prompts.js';
|
|
8
8
|
import { Icon } from '@adecore/ui';
|
|
9
|
-
import {
|
|
9
|
+
import { useChatHost } from '../../host.js';
|
|
10
10
|
/* One question of a request: its choices, "Something else…", or a written answer when it offers no choices. */
|
|
11
11
|
export function QuestionBody({ question, answer, onAnswer, onCommit, locked }) {
|
|
12
|
+
const host = useChatHost();
|
|
12
13
|
const { t } = useTranslation('agent-prompts');
|
|
13
|
-
const AnswerField =
|
|
14
|
+
const AnswerField = host.dictation.Textarea;
|
|
14
15
|
// The choices, then the "Something else…" field form one list with a single tab stop.
|
|
15
16
|
const items = useRef([]);
|
|
16
17
|
const shownQuestion = useRef(question.id);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { AccentSwatches } from '@adecore/ui';
|
|
3
|
-
import {
|
|
3
|
+
import { useChatHost } from '../host.js';
|
|
4
4
|
/* The colors an account may wear, the host's palette. */
|
|
5
5
|
export function AccountColors({ value, label, onChange }) {
|
|
6
|
-
const { all, featured, label: labelOf } =
|
|
6
|
+
const { all, featured, label: labelOf } = useChatHost().accents;
|
|
7
7
|
return _jsx(AccentSwatches, { value: value, label: label, accents: all, featured: featured, labelOf: labelOf, onValueChange: onChange });
|
|
8
8
|
}
|
|
@@ -6,7 +6,7 @@ import { AccountDot } from '../agents/AccountDot.js';
|
|
|
6
6
|
import { accountName, FOLDER_VARIABLES } from '../agents/accounts.js';
|
|
7
7
|
import { ConfirmDialog, DetailHeader, SettingsRow, SettingsSection } from '@adecore/ui/settings';
|
|
8
8
|
import { Button, copyText, Icon, Input, Switch, Tooltip } from '@adecore/ui';
|
|
9
|
-
import {
|
|
9
|
+
import { useChatHost } from '../host.js';
|
|
10
10
|
import { useChatScope } from '../scope.js';
|
|
11
11
|
import { removeAccount, saveAccount } from './account-actions.js';
|
|
12
12
|
import { AccountVariables } from './AccountVariables.js';
|
|
@@ -35,6 +35,7 @@ function NameField({ value, label, onSave }) {
|
|
|
35
35
|
export function AccountDetail({ provider, entry, canLogIn, loginBlocked, secretsAvailable, onRemoved }) {
|
|
36
36
|
const { t } = useTranslation('agent-providers');
|
|
37
37
|
const scope = useChatScope();
|
|
38
|
+
const host = useChatHost();
|
|
38
39
|
const [confirming, setConfirming] = useState(false);
|
|
39
40
|
const { id, account, status, isDefault } = entry;
|
|
40
41
|
const name = accountName(entry, provider.name);
|
|
@@ -43,7 +44,7 @@ export function AccountDetail({ provider, entry, canLogIn, loginBlocked, secrets
|
|
|
43
44
|
const signedIn = status?.state === 'ready';
|
|
44
45
|
const showFolder = () => {
|
|
45
46
|
copyText(folder);
|
|
46
|
-
|
|
47
|
+
host.notify({ kind: 'success', title: t('account.folderCopied'), description: folder });
|
|
47
48
|
};
|
|
48
49
|
const loginDetail = () => {
|
|
49
50
|
if (status !== null && TROUBLE.has(status.state) && status.message) {
|
|
@@ -54,16 +55,16 @@ export function AccountDetail({ provider, entry, canLogIn, loginBlocked, secrets
|
|
|
54
55
|
}
|
|
55
56
|
return status?.plan ? t('account.login.planDetail', { plan: status.plan }) : t('account.login.detail');
|
|
56
57
|
};
|
|
57
|
-
const loginButton = (_jsxs(Button, { variant: "secondary", disabled: loginBlocked !== null, onClick: () => void
|
|
58
|
+
const loginButton = (_jsxs(Button, { variant: "secondary", disabled: loginBlocked !== null, onClick: () => void host.openLogin?.(scope.id, provider.kind, id, name), children: [_jsx(Icon, { icon: LogIn, size: 14 }), signedIn ? t('account.login.logInAgain') : t('account.login.logIn')] }));
|
|
58
59
|
return (_jsxs(_Fragment, { children: [_jsx(DetailHeader, { mark: _jsx("span", { className: "grid h-6 shrink-0 place-items-center", children: _jsx(AccountDot, { color: account.color, className: "size-3" }) }), title: name, subtitle: _jsxs(_Fragment, { children: [_jsx(CliMark, { kind: provider.kind, size: 12, className: "text-text-muted" }), t('account.kind', { provider: provider.name })] }), actions: folder !== '' && (_jsx(Button, { variant: "secondary", onClick: showFolder, children: t('account.showFolder') })) }), _jsxs(SettingsSection, { children: [_jsx(SettingsRow, { label: t('account.enabled.label'), description: t('account.enabled.description'), control: _jsx(Switch, { checked: account.enabled !== false, label: t('account.enabled.label'), onCheckedChange: (checked) => {
|
|
59
60
|
const { enabled: _enabled, ...rest } = account;
|
|
60
|
-
void saveAccount(scope, id, checked ? rest : { ...rest, enabled: false });
|
|
61
|
-
} }) }), _jsx(SettingsRow, { label: t('account.name'), control: _jsx(NameField, { value: name, label: t('account.name'), onSave: (label) => void saveAccount(scope, id, { ...account, label }) }, name) }), _jsx(SettingsRow, { label: t('account.color'), control: _jsx(AccountColors, { value: account.color, label: t('account.color'), onChange: (color) => void saveAccount(scope, id, { ...account, color }) }) })] }), canLogIn && (_jsxs(SettingsSection, { title: t('account.login.title'), children: [_jsx(SettingsRow, { label: signedIn
|
|
61
|
+
void saveAccount(scope, host, id, checked ? rest : { ...rest, enabled: false });
|
|
62
|
+
} }) }), _jsx(SettingsRow, { label: t('account.name'), control: _jsx(NameField, { value: name, label: t('account.name'), onSave: (label) => void saveAccount(scope, host, id, { ...account, label }) }, name) }), _jsx(SettingsRow, { label: t('account.color'), control: _jsx(AccountColors, { value: account.color, label: t('account.color'), onChange: (color) => void saveAccount(scope, host, id, { ...account, color }) }) })] }), canLogIn && (_jsxs(SettingsSection, { title: t('account.login.title'), children: [_jsx(SettingsRow, { label: signedIn
|
|
62
63
|
? status?.email
|
|
63
64
|
? t('account.login.signedInAs', { email: status.email })
|
|
64
65
|
: t('account.login.signedIn')
|
|
65
66
|
: t('account.login.signedOut'), description: loginBlocked === null ? loginDetail() : `${loginDetail()} ${loginBlocked}`, control: loginBlocked === null ? (loginButton) : (_jsx(Tooltip, { label: loginBlocked, children: _jsx("span", { className: "inline-flex", children: loginButton }) })) }), _jsxs(SettingsRow, { label: t('account.folder.label'), children: [_jsx(Input, { mono: true, className: "h-8.5", value: folder, readOnly: true, "aria-label": t('account.folder.label') }), _jsx("p", { className: "-mt-1 text-xs text-text-muted", children: variable ? (_jsx(Trans, { t: t, i18nKey: "account.folder.detail", values: { variable }, components: { code: _jsx("code", { className: "font-mono text-code" }) } })) : (t('account.folder.detailPlain')) })] })] })), _jsx(AccountVariables, { id: id, account: account, secretsAvailable: secretsAvailable }, `${id}:${JSON.stringify(account.env ?? [])}`), _jsx(SettingsSection, { children: _jsx(SettingsRow, { label: t('account.remove.label'), description: isDefault ? t('account.remove.defaultNote') : t('account.remove.description'), control: _jsx(Button, { variant: "danger-outline", disabled: isDefault, onClick: () => setConfirming(true), children: t('account.remove.button') }) }) }), _jsx(ConfirmDialog, { open: confirming, onOpenChange: setConfirming, title: t('account.remove.confirmTitle', { account: name }), description: t('account.remove.confirmDescription', { folder }), confirmLabel: t('account.remove.confirm'), onConfirm: async () => {
|
|
66
|
-
await removeAccount(scope, id, provider.kind);
|
|
67
|
+
await removeAccount(scope, host, id, provider.kind);
|
|
67
68
|
onRemoved();
|
|
68
69
|
} })] }));
|
|
69
70
|
}
|
|
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import { useTranslation } from 'react-i18next';
|
|
4
4
|
import { Lock, LockOpen, Plus, X } from 'lucide-react';
|
|
5
|
+
import { useChatHost } from '../host.js';
|
|
5
6
|
import { useChatScope } from '../scope.js';
|
|
6
7
|
import { saveAccount } from './account-actions.js';
|
|
7
8
|
import { draftsOf, emptyDraft, variablesChanged, variablesOf, variablesProblem } from './variables.js';
|
|
@@ -14,6 +15,7 @@ import { Button, FormError, Icon, IconButton, Input, Tooltip } from '@adecore/ui
|
|
|
14
15
|
export function AccountVariables({ id, account, secretsAvailable }) {
|
|
15
16
|
const { t } = useTranslation('agent-providers');
|
|
16
17
|
const scope = useChatScope();
|
|
18
|
+
const host = useChatHost();
|
|
17
19
|
const [drafts, setDrafts] = useState(() => draftsOf(account.env));
|
|
18
20
|
const [saving, setSaving] = useState(false);
|
|
19
21
|
const changed = variablesChanged(drafts, account.env);
|
|
@@ -26,7 +28,7 @@ export function AccountVariables({ id, account, secretsAvailable }) {
|
|
|
26
28
|
const { env: _env, ...rest } = account;
|
|
27
29
|
setSaving(true);
|
|
28
30
|
try {
|
|
29
|
-
await saveAccount(scope, id, env.length === 0 ? rest : { ...rest, env });
|
|
31
|
+
await saveAccount(scope, host, id, env.length === 0 ? rest : { ...rest, env });
|
|
30
32
|
}
|
|
31
33
|
finally {
|
|
32
34
|
setSaving(false);
|
|
@@ -4,7 +4,7 @@ import clsx from 'clsx';
|
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
5
5
|
import { ChevronRight } from 'lucide-react';
|
|
6
6
|
import { freeAccountColor, mintAccountId } from '../agents/accounts.js';
|
|
7
|
-
import {
|
|
7
|
+
import { useChatHost } from '../host.js';
|
|
8
8
|
import { useChatScope } from '../scope.js';
|
|
9
9
|
import { createAccount, linkAccount } from './account-actions.js';
|
|
10
10
|
import { AccountColors } from './AccountColors.js';
|
|
@@ -19,8 +19,9 @@ import { providerAccountsOf } from '../state/provider-accounts.js';
|
|
|
19
19
|
export function AddAccountForm({ provider, entries, onCancel, onAdded }) {
|
|
20
20
|
const { t } = useTranslation('agent-providers');
|
|
21
21
|
const scope = useChatScope();
|
|
22
|
+
const { accents } = useChatHost();
|
|
22
23
|
const [name, setName] = useState('');
|
|
23
|
-
const [color, setColor] = useState(() => freeAccountColor(entries,
|
|
24
|
+
const [color, setColor] = useState(() => freeAccountColor(entries, accents, accents.current()));
|
|
24
25
|
const [advanced, setAdvanced] = useState(false);
|
|
25
26
|
const [folder, setFolder] = useState('');
|
|
26
27
|
const [busy, setBusy] = useState(false);
|
|
@@ -7,7 +7,7 @@ import { AccountDot } from '../agents/AccountDot.js';
|
|
|
7
7
|
import { ACCOUNT_TONE_CLASSES, accountName, accountsOfKind, accountStatusLine } from '../agents/accounts.js';
|
|
8
8
|
import { ErrorBoundary, Icon, IconButton, SectionLabel, Skeleton } from '@adecore/ui';
|
|
9
9
|
import { MasterDetail } from '@adecore/ui/settings';
|
|
10
|
-
import {
|
|
10
|
+
import { useChatHost } from '../host.js';
|
|
11
11
|
import { useChatScope } from '../scope.js';
|
|
12
12
|
import { AccountDetail } from './AccountDetail.js';
|
|
13
13
|
import { AddAccountForm } from './AddAccountForm.js';
|
|
@@ -26,8 +26,9 @@ export function ProvidersPane({ target = null, detailOf, defaults = true }) {
|
|
|
26
26
|
const providers = useProviders((s) => s.providers);
|
|
27
27
|
const loaded = useProviders((s) => s.loaded);
|
|
28
28
|
const accounts = useProviderAccounts((s) => s.accounts);
|
|
29
|
-
const
|
|
30
|
-
const
|
|
29
|
+
const host = useChatHost();
|
|
30
|
+
const { openLogin } = host;
|
|
31
|
+
const loginBlocked = host.useLoginBlocked(scopeId);
|
|
31
32
|
const [picked, setPicked] = useState(() => (target === 'providers.apple' ? { kind: 'cli', cli: 'apple' } : null));
|
|
32
33
|
const installed = useMemo(() => providers.filter((provider) => provider.installed || provider.kind === 'apple'), [providers]);
|
|
33
34
|
const missing = useMemo(() => providers.filter((provider) => !provider.installed && provider.kind !== 'apple'), [providers]);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { AgentKind, ProviderAccount, ProviderAccountMap } from '@adecore/agent-contracts';
|
|
2
|
+
import type { ChatHost } from '../host.js';
|
|
2
3
|
import type { ChatScope } from '../scope.js';
|
|
3
|
-
export declare function saveAccounts(scope: ChatScope, accounts: ProviderAccountMap): Promise<boolean>;
|
|
4
|
-
export declare function saveAccount(scope: ChatScope, id: string, account: ProviderAccount): Promise<boolean>;
|
|
5
|
-
export declare function removeAccount(scope: ChatScope, id: string, kind: AgentKind): Promise<void>;
|
|
4
|
+
export declare function saveAccounts(scope: ChatScope, host: Pick<ChatHost, 'notify'>, accounts: ProviderAccountMap): Promise<boolean>;
|
|
5
|
+
export declare function saveAccount(scope: ChatScope, host: Pick<ChatHost, 'notify'>, id: string, account: ProviderAccount): Promise<boolean>;
|
|
6
|
+
export declare function removeAccount(scope: ChatScope, host: Pick<ChatHost, 'notify'>, id: string, kind: AgentKind): Promise<void>;
|
|
6
7
|
export declare function createAccount(scope: ChatScope, kind: AgentKind, label: string, color: string): Promise<string>;
|
|
7
8
|
export declare function linkAccount(scope: ChatScope, id: string, account: ProviderAccount): Promise<void>;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import i18next from 'i18next';
|
|
2
2
|
import { accountFor, readChatPreferences, rememberChatAccount } from '../chat/preferences.js';
|
|
3
|
-
import { chatHost } from '../host.js';
|
|
4
3
|
import { providerAccountsOf, useProviderAccountsStore } from '../state/provider-accounts.js';
|
|
5
4
|
function words(key, values) {
|
|
6
5
|
return i18next.t(`agent-providers:${key}`, values);
|
|
@@ -15,28 +14,28 @@ function linkTo(scope) {
|
|
|
15
14
|
return scope.transport;
|
|
16
15
|
}
|
|
17
16
|
/* The whole map, as `accounts.save` takes it. Answers false when the host refused, which a toast then says. */
|
|
18
|
-
export async function saveAccounts(scope, accounts) {
|
|
17
|
+
export async function saveAccounts(scope, host, accounts) {
|
|
19
18
|
try {
|
|
20
19
|
useProviderAccountsStore.getState().set(scope.id, await linkTo(scope).request('accounts.save', { accounts }));
|
|
21
20
|
return true;
|
|
22
21
|
}
|
|
23
22
|
catch (e) {
|
|
24
|
-
|
|
23
|
+
host.notify({ id: `providers-save-${scope.id}`, kind: 'error', title: words('account.saveFailed'), description: reason(e) });
|
|
25
24
|
return false;
|
|
26
25
|
}
|
|
27
26
|
}
|
|
28
27
|
/* One account changed and every other one as the host last said. */
|
|
29
|
-
export function saveAccount(scope, id, account) {
|
|
28
|
+
export function saveAccount(scope, host, id, account) {
|
|
30
29
|
const current = providerAccountsOf(scope.id).accounts?.accounts ?? {};
|
|
31
|
-
return saveAccounts(scope, { ...current, [id]: account });
|
|
30
|
+
return saveAccounts(scope, host, { ...current, [id]: account });
|
|
32
31
|
}
|
|
33
32
|
/*
|
|
34
33
|
* Forgets an account; its folder stays where it is. A pick for new agents that named it goes back to
|
|
35
34
|
* the CLI's default account, since no chat started from it yet.
|
|
36
35
|
*/
|
|
37
|
-
export async function removeAccount(scope, id, kind) {
|
|
36
|
+
export async function removeAccount(scope, host, id, kind) {
|
|
38
37
|
const { [id]: _gone, ...rest } = providerAccountsOf(scope.id).accounts?.accounts ?? {};
|
|
39
|
-
if (!(await saveAccounts(scope, rest))) {
|
|
38
|
+
if (!(await saveAccounts(scope, host, rest))) {
|
|
40
39
|
throw new Error(words('account.saveFailed'));
|
|
41
40
|
}
|
|
42
41
|
if (accountFor(readChatPreferences(), scope.id, kind) === id) {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { AccountDot } from '../agents/AccountDot.js';
|
|
2
|
+
export { AgentIcon } from '../agents/AgentIcon.js';
|
|
3
|
+
export { ModelOptionControl } from '../agents/ModelOptionControl.js';
|
|
4
|
+
export { ProviderLogo } from '../agents/ProviderLogo.js';
|
|
5
|
+
export { type AccountEntry, accountsOfKind, accountName, ACCOUNT_TONE_CLASSES, accountStatusLine, canContinueOn, type AccountTone } from '../agents/accounts.js';
|
|
6
|
+
export { modelName, useModelName, shortModelName } from '../agents/model-name.js';
|
|
7
|
+
export { optionValue, carryOptions } from '../agents/model-options.js';
|
|
8
|
+
export { modelRequirementOf, type ModelRequirement } from '../agents/model-requirement.js';
|
|
9
|
+
export { AccountColors } from './AccountColors.js';
|
|
10
|
+
export { AccountDetail } from './AccountDetail.js';
|
|
11
|
+
export { AccountVariables } from './AccountVariables.js';
|
|
12
|
+
export { AddAccountForm } from './AddAccountForm.js';
|
|
13
|
+
export { CliDetail } from './CliDetail.js';
|
|
14
|
+
export { ProvidersPane } from './ProvidersPane.js';
|
|
15
|
+
export { saveAccounts, saveAccount, removeAccount, createAccount, linkAccount } from './account-actions.js';
|
|
16
|
+
export { CliMark, CliTile } from './parts.js';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Public API: exports.test.ts snapshots this list, so a name added or dropped here is an API change.
|
|
2
|
+
export { AccountDot } from '../agents/AccountDot.js';
|
|
3
|
+
export { AgentIcon } from '../agents/AgentIcon.js';
|
|
4
|
+
export { ModelOptionControl } from '../agents/ModelOptionControl.js';
|
|
5
|
+
export { ProviderLogo } from '../agents/ProviderLogo.js';
|
|
6
|
+
export { accountsOfKind, accountName, ACCOUNT_TONE_CLASSES, accountStatusLine, canContinueOn } from '../agents/accounts.js';
|
|
7
|
+
export { modelName, useModelName, shortModelName } from '../agents/model-name.js';
|
|
8
|
+
export { optionValue, carryOptions } from '../agents/model-options.js';
|
|
9
|
+
export { modelRequirementOf } from '../agents/model-requirement.js';
|
|
10
|
+
export { AccountColors } from './AccountColors.js';
|
|
11
|
+
export { AccountDetail } from './AccountDetail.js';
|
|
12
|
+
export { AccountVariables } from './AccountVariables.js';
|
|
13
|
+
export { AddAccountForm } from './AddAccountForm.js';
|
|
14
|
+
export { CliDetail } from './CliDetail.js';
|
|
15
|
+
export { ProvidersPane } from './ProvidersPane.js';
|
|
16
|
+
export { saveAccounts, saveAccount, removeAccount, createAccount, linkAccount } from './account-actions.js';
|
|
17
|
+
export { CliMark, CliTile } from './parts.js';
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import type { ProviderInfo } from '@adecore/agent-contracts';
|
|
1
|
+
import type { ProviderCapabilities, ProviderInfo } from '@adecore/agent-contracts';
|
|
2
2
|
export declare function providerAbilities(provider: ProviderInfo): string;
|
|
3
|
+
export declare function canSteer(capabilities: ProviderCapabilities | undefined): boolean;
|
|
@@ -5,3 +5,7 @@ export function providerAbilities(provider) {
|
|
|
5
5
|
const status = provider.capabilities.hooks ? i18next.t('agent-providers:abilities.reportsStatus') : i18next.t('agent-providers:abilities.noStatus');
|
|
6
6
|
return `${where} ${status}`;
|
|
7
7
|
}
|
|
8
|
+
/* Whether a message sent while a turn runs may join it. Undefined while the host has not answered `provider.list`, which steers nothing. */
|
|
9
|
+
export function canSteer(capabilities) {
|
|
10
|
+
return capabilities?.steer === true;
|
|
11
|
+
}
|
package/dist/state/chats.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useContext, useMemo } from 'react';
|
|
2
2
|
import { create } from 'zustand';
|
|
3
|
+
import { appendToolOutput } from '@adecore/agent-contracts/text';
|
|
3
4
|
import { ChatScopeContext, useChatScope } from '../scope.js';
|
|
4
5
|
function isWaiting(item) {
|
|
5
6
|
return (item?.kind === 'approval' && item.decision === 'pending') || (item?.kind === 'question' && item.state === 'pending');
|
|
@@ -39,7 +40,8 @@ export function prependPage(state, cursor, page) {
|
|
|
39
40
|
const olderIds = new Set(older.map((item) => item.id));
|
|
40
41
|
const items = { ...state.items };
|
|
41
42
|
for (const item of older) {
|
|
42
|
-
|
|
43
|
+
// A request from before the page that this client already holds came in live, which is never older than the page.
|
|
44
|
+
items[item.id] = state.items[item.id] ?? item;
|
|
43
45
|
}
|
|
44
46
|
const order = [...olderIds, ...state.order];
|
|
45
47
|
if (page.history.cursor === null) {
|
|
@@ -103,7 +105,7 @@ export function applyEvent(state, event) {
|
|
|
103
105
|
}
|
|
104
106
|
if (item?.kind === 'tool' && item.state === 'running') {
|
|
105
107
|
const progress = item.progress ?? { startedAt: null, description: null, output: null };
|
|
106
|
-
const grown = { ...item, progress: { ...progress, output: (progress.output
|
|
108
|
+
const grown = { ...item, progress: { ...progress, output: appendToolOutput(progress.output, event.text) } };
|
|
107
109
|
return { ...state, items: { ...state.items, [event.itemId]: grown } };
|
|
108
110
|
}
|
|
109
111
|
return state;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { type ChatState, type ChatsById, type ChatStatuses, type ChatSink, prependPage, waitingRequestsOf, applyEvent, useChats, chatSink, useChatRow, useReportedModels, useCurrentItem, type ChatHistoryPage, type ChatPage } from './chats.js';
|
|
2
|
+
export { useProviderAccountsStore, useProviderAccounts, providerAccountsOf, knownAccounts, watchProviderAccounts, type ProviderAccountsRow } from './provider-accounts.js';
|
|
3
|
+
export { useProvidersStore, useProviders, providersOf, providerSinkFor, type ProvidersRow } from './providers.js';
|
|
4
|
+
export { type UsageMetric, USAGE_PREFERENCES_KEY, usagePreferencesKey, dayOf, windowFor, summaryPayload, reloadUsagePreferences, useUsageStore, useUsage, type UsagePeriod, type UsageView } from './usage.js';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// Public API: exports.test.ts snapshots this list, so a name added or dropped here is an API change.
|
|
2
|
+
export { prependPage, waitingRequestsOf, applyEvent, useChats, chatSink, useChatRow, useReportedModels, useCurrentItem } from './chats.js';
|
|
3
|
+
export { useProviderAccountsStore, useProviderAccounts, providerAccountsOf, knownAccounts, watchProviderAccounts } from './provider-accounts.js';
|
|
4
|
+
export { useProvidersStore, useProviders, providersOf, providerSinkFor } from './providers.js';
|
|
5
|
+
export { USAGE_PREFERENCES_KEY, usagePreferencesKey, dayOf, windowFor, summaryPayload, reloadUsagePreferences, useUsageStore, useUsage } from './usage.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { PROMPT_SAMPLES } from './prompts.js';
|
package/dist/theme.css
CHANGED
|
@@ -91,13 +91,14 @@
|
|
|
91
91
|
/*
|
|
92
92
|
* A chat that is a view of its own reads in a column. The scroller keeps the full width of the
|
|
93
93
|
* main column, so its scrollbar sits at that column's right edge and nothing jumps when the
|
|
94
|
-
* thread grows past a screenful; only the rows and the composer inside it are centered.
|
|
94
|
+
* thread grows past a screenful; only the rows and the composer inside it are centered. The
|
|
95
|
+
* width is the person's reading width (`chat/reading-width.ts`).
|
|
95
96
|
*/
|
|
96
|
-
.chat-column .chat-column-content { margin-inline: auto; max-width: 768px; }
|
|
97
|
+
.chat-column .chat-column-content { margin-inline: auto; max-width: var(--chat-measure, 768px); }
|
|
97
98
|
/* Wide pages clear the scrubber even when the reply column needs no extra padding. */
|
|
98
99
|
.chat-wide-content { max-width: calc(100% - 2 * var(--chat-wide-inset, 0px)); }
|
|
99
100
|
/* Wider by the input's inset (`.composer-input .cm-content` padding plus the card's border), so what is typed lines up with the thread. */
|
|
100
|
-
.chat-column .chat-composer-content { margin-inline: auto; max-width: calc(768px + 2 * 21px); }
|
|
101
|
+
.chat-column .chat-composer-content { margin-inline: auto; max-width: calc(var(--chat-measure, 768px) + 2 * 21px); }
|
|
101
102
|
|
|
102
103
|
/* A diff inside a chat tool block; the library paints its own colors inside a shadow root and
|
|
103
104
|
takes the face it draws them in through these variables. */
|
|
@@ -184,6 +185,15 @@
|
|
|
184
185
|
--tw-prose-th-borders: var(--border);
|
|
185
186
|
--tw-prose-td-borders: var(--border);
|
|
186
187
|
}
|
|
188
|
+
/* A muted `Markdown`, such as a thought the model had before it answered. */
|
|
189
|
+
.prose.chat-markdown[data-muted] {
|
|
190
|
+
--tw-prose-body: var(--text-muted);
|
|
191
|
+
--tw-prose-headings: var(--text-muted);
|
|
192
|
+
--tw-prose-bold: var(--text-muted);
|
|
193
|
+
--tw-prose-quotes: var(--text-muted);
|
|
194
|
+
--tw-prose-code: var(--text-muted);
|
|
195
|
+
--tw-prose-pre-code: var(--text-muted);
|
|
196
|
+
}
|
|
187
197
|
/* Headings stay on the app's scale, which is flatter than the one prose brings. */
|
|
188
198
|
.chat-markdown :is(h1, h2, h3, h4) { font-weight: 600; line-height: round(1.3em, 1px); }
|
|
189
199
|
.chat-markdown h1 { font-size: var(--text-lg); }
|
|
@@ -5,7 +5,7 @@ import { CircleHelp, Folder, Info } from 'lucide-react';
|
|
|
5
5
|
import { useTranslation } from 'react-i18next';
|
|
6
6
|
import { EmptyState, Icon, SectionLabel, Segmented, Tooltip } from '@adecore/ui';
|
|
7
7
|
import { useChatScope } from '../scope.js';
|
|
8
|
-
import {
|
|
8
|
+
import { useChatHost } from '../host.js';
|
|
9
9
|
import { ProviderLogo } from '../agents/ProviderLogo.js';
|
|
10
10
|
import { USAGE_PROVIDERS, totalTokensOf } from '@adecore/agent-contracts';
|
|
11
11
|
import { modelNameFromSlug } from '../agents/model-name.js';
|
|
@@ -33,8 +33,9 @@ function ModelRows({ models, metric, total }) {
|
|
|
33
33
|
}
|
|
34
34
|
/* One project's row, under the name and the mark its host gives it, or its folder's own under a folder. */
|
|
35
35
|
function ProjectRow({ project, top, money }) {
|
|
36
|
+
const host = useChatHost();
|
|
36
37
|
// The usage on screen is one host's, so the look of a project is that host's too.
|
|
37
|
-
const look =
|
|
38
|
+
const look = host.useProjectLook(useChatScope().id, project.projectId);
|
|
38
39
|
return (_jsxs("div", { className: `${ROW} h-auto items-start py-1.5`, children: [_jsx("span", { className: "mt-px flex", children: look?.mark ?? (_jsx("span", { className: "text-text-faint", children: _jsx(Icon, { icon: Folder, size: 16 }) })) }), _jsxs("span", { className: "flex min-w-0 grow flex-col", children: [_jsx("span", { className: "truncate", children: look?.name ?? project.name }), _jsx("span", { className: "truncate text-text-faint", children: shortPath(project.folder) })] }), _jsx("span", { className: "mt-1 flex h-[9px] w-32 shrink-0 overflow-hidden rounded-full bg-surface-sunken", children: USAGE_PROVIDERS.map((provider) => {
|
|
39
40
|
const share = project.byProvider[provider];
|
|
40
41
|
const width = barWidth(share?.costUsd ?? 0, top);
|
|
@@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next';
|
|
|
4
4
|
import { LogIn } from 'lucide-react';
|
|
5
5
|
import { AccountDot } from '../agents/AccountDot.js';
|
|
6
6
|
import { Button, Icon, SectionLabel, Segmented, Tooltip, useNow } from '@adecore/ui';
|
|
7
|
-
import {
|
|
7
|
+
import { useChatHost } from '../host.js';
|
|
8
8
|
import { PROVIDER_COLORS, PROVIDER_LABELS } from './format.js';
|
|
9
9
|
import { accountNote, checkedLabel, hasSeveralAccounts, isSignedOut } from './limit-groups.js';
|
|
10
10
|
import { WindowBar } from './LimitsList.js';
|
|
@@ -32,14 +32,15 @@ function LimitCard({ account, named, now, login }) {
|
|
|
32
32
|
* credential: every CLI holds its own login and answers the question when the daemon starts one and asks.
|
|
33
33
|
*/
|
|
34
34
|
export function UsageLimits() {
|
|
35
|
+
const host = useChatHost();
|
|
35
36
|
const { t } = useTranslation('agent-usage');
|
|
36
37
|
const limits = useUsageLimits();
|
|
37
38
|
const groups = useLimitGroups(limits);
|
|
38
39
|
const now = useNow(MINUTE_MS);
|
|
39
40
|
const scopeId = useChatScope().id;
|
|
40
41
|
const loginCommands = useProviderAccountsStore((s) => s.byScope[scopeId]?.accounts?.loginCommands);
|
|
41
|
-
const { openLogin } =
|
|
42
|
-
const blocked =
|
|
42
|
+
const { openLogin } = host;
|
|
43
|
+
const blocked = host.useLoginBlocked(scopeId);
|
|
43
44
|
const [filter, setFilter] = useState('all');
|
|
44
45
|
if (limits === null) {
|
|
45
46
|
return null;
|
package/dist/usage/UsagePage.js
CHANGED
|
@@ -5,7 +5,7 @@ import { ChartNoAxesColumn, RefreshCw } from 'lucide-react';
|
|
|
5
5
|
import { USAGE_PROVIDERS } from '@adecore/agent-contracts';
|
|
6
6
|
import { Button, CloseButton, Dialog, EmptyState, FormError, IconButton, Segmented, Select, Skeleton } from '@adecore/ui';
|
|
7
7
|
import { AccountDot } from '../agents/AccountDot.js';
|
|
8
|
-
import {
|
|
8
|
+
import { useChatHost } from '../host.js';
|
|
9
9
|
import { useChatScope } from '../scope.js';
|
|
10
10
|
import { useProvidersStore } from '../state/providers.js';
|
|
11
11
|
import { askedKey, summaryPayload, USAGE_PERIODS, useUsage, useUsageStore } from '../state/usage.js';
|
|
@@ -31,6 +31,7 @@ function useAnswering(transport) {
|
|
|
31
31
|
* agent looks like too, and the way to fix that is the agent settings.
|
|
32
32
|
*/
|
|
33
33
|
function HostAgents() {
|
|
34
|
+
const host = useChatHost();
|
|
34
35
|
const { t } = useTranslation('agent-usage');
|
|
35
36
|
const { id } = useChatScope();
|
|
36
37
|
const row = useProvidersStore((s) => s.byScope[id]);
|
|
@@ -38,7 +39,7 @@ function HostAgents() {
|
|
|
38
39
|
if (!row?.loaded) {
|
|
39
40
|
return null;
|
|
40
41
|
}
|
|
41
|
-
return (_jsxs("div", { className: "flex flex-col items-center gap-2", children: [_jsx("p", { className: "text-xs text-text-muted", children: installed.length === 0 ? t('agents.none') : t('agents.installed', { list: installed.map((provider) => provider.name).join(', ') }) }), _jsx(Button, { size: "sm", variant: "secondary", onClick: () =>
|
|
42
|
+
return (_jsxs("div", { className: "flex flex-col items-center gap-2", children: [_jsx("p", { className: "text-xs text-text-muted", children: installed.length === 0 ? t('agents.none') : t('agents.installed', { list: installed.map((provider) => provider.name).join(', ') }) }), _jsx(Button, { size: "sm", variant: "secondary", onClick: () => host.openSettings('agents'), children: t('agents.settings') })] }));
|
|
42
43
|
}
|
|
43
44
|
/*
|
|
44
45
|
* Asks the host on screen for the period that is up, keeps the answer under the key of the question
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { WindowBar, LimitsList, AccountLimitsList } from './LimitsList.js';
|
|
2
|
+
export { UsageBreakdown } from './UsageBreakdown.js';
|
|
3
|
+
export { UsageChart } from './UsageChart.js';
|
|
4
|
+
export { UsageDialog } from './UsageDialog.js';
|
|
5
|
+
export { UsageLimits } from './UsageLimits.js';
|
|
6
|
+
export { UsageLimitsCard } from './UsageLimitsCard.js';
|
|
7
|
+
export { UsagePage } from './UsagePage.js';
|
|
8
|
+
export { UsagePane } from './UsagePane.js';
|
|
9
|
+
export { UsageSummary } from './UsageSummary.js';
|
|
10
|
+
export { UsageTiles } from './UsageTiles.js';
|
|
11
|
+
export { formatClock, type UsageCurrency } from './format.js';
|
|
12
|
+
export type { LimitAccount, LimitGroup } from './limit-groups.js';
|
|
13
|
+
export { useLimitGroups } from './limits.js';
|
|
14
|
+
export { useMoney } from './money.js';
|
|
15
|
+
export { niceScale, labelEveryFor, deriveUsage, type ChartSlot, type ProviderTotal, type DerivedUsage } from './summary.js';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Public API: exports.test.ts snapshots this list, so a name added or dropped here is an API change.
|
|
2
|
+
export { WindowBar, LimitsList, AccountLimitsList } from './LimitsList.js';
|
|
3
|
+
export { UsageBreakdown } from './UsageBreakdown.js';
|
|
4
|
+
export { UsageChart } from './UsageChart.js';
|
|
5
|
+
export { UsageDialog } from './UsageDialog.js';
|
|
6
|
+
export { UsageLimits } from './UsageLimits.js';
|
|
7
|
+
export { UsageLimitsCard } from './UsageLimitsCard.js';
|
|
8
|
+
export { UsagePage } from './UsagePage.js';
|
|
9
|
+
export { UsagePane } from './UsagePane.js';
|
|
10
|
+
export { UsageSummary } from './UsageSummary.js';
|
|
11
|
+
export { UsageTiles } from './UsageTiles.js';
|
|
12
|
+
export { formatClock } from './format.js';
|
|
13
|
+
export { useLimitGroups } from './limits.js';
|
|
14
|
+
export { useMoney } from './money.js';
|
|
15
|
+
export { niceScale, labelEveryFor, deriveUsage } from './summary.js';
|