@adecore/agents-react 0.38.0 → 0.39.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.
Files changed (51) hide show
  1. package/dist/agents/AgentModelLabel.d.ts +10 -0
  2. package/dist/agents/AgentModelLabel.js +97 -0
  3. package/dist/chat/ui/Composer.js +385 -360
  4. package/dist/chat/ui/Pickers.d.ts +2 -1
  5. package/dist/chat/ui/Pickers.js +126 -123
  6. package/dist/chat/ui/PromptEditor.d.ts +19 -0
  7. package/dist/chat/ui/PromptEditor.js +115 -0
  8. package/dist/chat/ui/Timeline.d.ts +2 -1
  9. package/dist/chat/ui/Timeline.js +13 -1
  10. package/dist/chat/ui/composer/ComposerControls.d.ts +3 -0
  11. package/dist/chat/ui/composer/ComposerControls.js +235 -38
  12. package/dist/chat/ui/composer/key-handler.d.ts +1 -1
  13. package/dist/chat/ui/composer/key-handler.js +3 -11
  14. package/dist/chat/ui/composer/prompt-picks.d.ts +4 -0
  15. package/dist/chat/ui/composer/prompt-picks.js +14 -0
  16. package/dist/chat/ui/composer/use-composer-menus.d.ts +4 -49
  17. package/dist/chat/ui/composer/use-composer-menus.js +65 -519
  18. package/dist/chat/ui/composer/use-prompt-menus.d.ts +73 -0
  19. package/dist/chat/ui/composer/use-prompt-menus.js +536 -0
  20. package/dist/chat/ui/index.d.ts +3 -0
  21. package/dist/chat/ui/index.js +2 -0
  22. package/dist/host-hooks.d.ts +2 -1
  23. package/dist/host-hooks.js +6 -0
  24. package/dist/host.d.ts +17 -1
  25. package/dist/index.d.ts +1 -1
  26. package/dist/locales/en/agent-chat.d.ts +1 -0
  27. package/dist/locales/en/agent-chat.js +1 -0
  28. package/dist/locales/nl/agent-chat.d.ts +1 -0
  29. package/dist/locales/nl/agent-chat.js +1 -0
  30. package/dist/providers/index.d.ts +1 -0
  31. package/dist/providers/index.js +1 -0
  32. package/dist/theme.css +3 -0
  33. package/package.json +8 -8
  34. package/src/agents/AgentModelLabel.tsx +40 -0
  35. package/src/chat/ui/Composer.tsx +12 -3
  36. package/src/chat/ui/Pickers.tsx +4 -1
  37. package/src/chat/ui/PromptEditor.tsx +130 -0
  38. package/src/chat/ui/Timeline.tsx +22 -1
  39. package/src/chat/ui/composer/ComposerControls.tsx +65 -15
  40. package/src/chat/ui/composer/key-handler.ts +3 -9
  41. package/src/chat/ui/composer/prompt-picks.ts +17 -0
  42. package/src/chat/ui/composer/use-composer-menus.ts +18 -275
  43. package/src/chat/ui/composer/use-prompt-menus.ts +341 -0
  44. package/src/chat/ui/index.ts +3 -0
  45. package/src/host-hooks.ts +9 -1
  46. package/src/host.ts +27 -1
  47. package/src/index.ts +2 -0
  48. package/src/locales/en/agent-chat.ts +1 -0
  49. package/src/locales/nl/agent-chat.ts +1 -0
  50. package/src/providers/index.ts +1 -0
  51. package/src/theme.css +3 -0
@@ -1,19 +1,225 @@
1
1
  import { c as _c } from "react/compiler-runtime";
2
- import { useRef } from 'react';
2
+ import { useRef, useState } from 'react';
3
3
  import { useTranslation } from 'react-i18next';
4
- import { ArrowUp, Play, Plus, Square } from 'lucide-react';
5
- import { Button, ErrorBoundary, Icon, Tooltip } from '@adecore/ui';
4
+ import clsx from 'clsx';
5
+ import { ArrowUp, ChevronDown, Play, Plus, Square } from 'lucide-react';
6
+ import { Button, ErrorBoundary, Icon, Menu, Tooltip } from '@adecore/ui';
6
7
  import { useChatHost } from '../../../host.js';
7
8
  import { useChatScope } from '../../../scope.js';
8
9
  import { useProviders } from '../../../state/providers.js';
9
10
  import { useAccountChoice } from '../../account-choice.js';
10
11
  import { composerStopLabel } from '../../subagent-list.js';
12
+ import { HostMenuItems } from '../HostMenuItems.js';
11
13
  import { StashPicker } from '../Pickers.js';
12
14
  import { RunSettings } from '../RunSettings.js';
13
- /* The row under the box: attach, the chat's settings, the stash, the app's own control, and stop and send. */
15
+ /* The send button, split with a chevron that opens the host's send actions when it has any. */
14
16
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
17
+ function SendButton(t0) {
18
+ const $ = _c(38);
19
+ const {
20
+ send,
21
+ writable
22
+ } = t0;
23
+ const {
24
+ t
25
+ } = useTranslation("agent-chat");
26
+ const [box, setBox] = useState(null);
27
+ const split = send.actions.length > 0;
28
+ const t1 = send.label;
29
+ const t2 = send.kbd;
30
+ const t3 = split ? "focus-visible:-outline-offset-2" : "rounded-full";
31
+ let t4;
32
+ if ($[0] !== t3) {
33
+ t4 = clsx("flex h-9 w-9 shrink-0 items-center justify-center bg-accent text-accent-text hover:brightness-90 disabled:opacity-50 disabled:hover:brightness-100", t3);
34
+ $[0] = t3;
35
+ $[1] = t4;
36
+ } else {
37
+ t4 = $[1];
38
+ }
39
+ let t5;
40
+ if ($[2] !== send) {
41
+ t5 = event => send.onSend(event.altKey);
42
+ $[2] = send;
43
+ $[3] = t5;
44
+ } else {
45
+ t5 = $[3];
46
+ }
47
+ let t6;
48
+ if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
49
+ t6 = /*#__PURE__*/_jsx(Icon, {
50
+ icon: ArrowUp,
51
+ size: 16
52
+ });
53
+ $[4] = t6;
54
+ } else {
55
+ t6 = $[4];
56
+ }
57
+ let t7;
58
+ if ($[5] !== send.disabled || $[6] !== t4 || $[7] !== t5) {
59
+ t7 = /*#__PURE__*/_jsx("button", {
60
+ className: t4,
61
+ disabled: send.disabled,
62
+ onClick: t5,
63
+ children: t6
64
+ });
65
+ $[5] = send.disabled;
66
+ $[6] = t4;
67
+ $[7] = t5;
68
+ $[8] = t7;
69
+ } else {
70
+ t7 = $[8];
71
+ }
72
+ let t8;
73
+ if ($[9] !== send.kbd || $[10] !== send.label || $[11] !== t7) {
74
+ t8 = /*#__PURE__*/_jsx(Tooltip, {
75
+ label: t1,
76
+ kbd: t2,
77
+ name: true,
78
+ children: t7
79
+ });
80
+ $[9] = send.kbd;
81
+ $[10] = send.label;
82
+ $[11] = t7;
83
+ $[12] = t8;
84
+ } else {
85
+ t8 = $[12];
86
+ }
87
+ const button = t8;
88
+ if (!split) {
89
+ return button;
90
+ }
91
+ const {
92
+ draft
93
+ } = send;
94
+ let t9;
95
+ if ($[13] !== t) {
96
+ t9 = t("composer.sendActions");
97
+ $[13] = t;
98
+ $[14] = t9;
99
+ } else {
100
+ t9 = $[14];
101
+ }
102
+ let t10;
103
+ if ($[15] === Symbol.for("react.memo_cache_sentinel")) {
104
+ t10 = /*#__PURE__*/_jsx("button", {
105
+ type: "button",
106
+ className: "relative flex h-9 w-6 shrink-0 items-center justify-center bg-accent text-accent-text before:absolute before:inset-y-0 before:left-0 before:my-auto before:h-4 before:w-px before:bg-current/30 before:content-[\"\"] hover:brightness-90 focus-visible:-outline-offset-2 disabled:opacity-50 disabled:hover:brightness-100"
107
+ });
108
+ $[15] = t10;
109
+ } else {
110
+ t10 = $[15];
111
+ }
112
+ const t11 = !writable;
113
+ let t12;
114
+ if ($[16] === Symbol.for("react.memo_cache_sentinel")) {
115
+ t12 = /*#__PURE__*/_jsx(Icon, {
116
+ icon: ChevronDown,
117
+ size: 14
118
+ });
119
+ $[16] = t12;
120
+ } else {
121
+ t12 = $[16];
122
+ }
123
+ let t13;
124
+ if ($[17] !== t11) {
125
+ t13 = /*#__PURE__*/_jsx(Menu.Trigger, {
126
+ render: t10,
127
+ disabled: t11,
128
+ children: t12
129
+ });
130
+ $[17] = t11;
131
+ $[18] = t13;
132
+ } else {
133
+ t13 = $[18];
134
+ }
135
+ let t14;
136
+ if ($[19] !== t13 || $[20] !== t9) {
137
+ t14 = /*#__PURE__*/_jsx(Tooltip, {
138
+ label: t9,
139
+ name: true,
140
+ children: t13
141
+ });
142
+ $[19] = t13;
143
+ $[20] = t9;
144
+ $[21] = t14;
145
+ } else {
146
+ t14 = $[21];
147
+ }
148
+ let t15;
149
+ if ($[22] !== draft || $[23] !== send.actions) {
150
+ let t16;
151
+ if ($[25] !== draft) {
152
+ t16 = action => ({
153
+ ...action,
154
+ run: () => action.run(draft)
155
+ });
156
+ $[25] = draft;
157
+ $[26] = t16;
158
+ } else {
159
+ t16 = $[26];
160
+ }
161
+ t15 = send.actions.map(t16);
162
+ $[22] = draft;
163
+ $[23] = send.actions;
164
+ $[24] = t15;
165
+ } else {
166
+ t15 = $[24];
167
+ }
168
+ let t16;
169
+ if ($[27] !== t15) {
170
+ t16 = /*#__PURE__*/_jsx(HostMenuItems, {
171
+ actions: t15
172
+ });
173
+ $[27] = t15;
174
+ $[28] = t16;
175
+ } else {
176
+ t16 = $[28];
177
+ }
178
+ let t17;
179
+ if ($[29] !== box || $[30] !== t16) {
180
+ t17 = /*#__PURE__*/_jsx(Menu.Popup, {
181
+ anchor: box,
182
+ side: "top",
183
+ sideOffset: 8,
184
+ align: "end",
185
+ className: "min-w-48",
186
+ children: t16
187
+ });
188
+ $[29] = box;
189
+ $[30] = t16;
190
+ $[31] = t17;
191
+ } else {
192
+ t17 = $[31];
193
+ }
194
+ let t18;
195
+ if ($[32] !== t14 || $[33] !== t17) {
196
+ t18 = /*#__PURE__*/_jsxs(Menu.Root, {
197
+ children: [t14, t17]
198
+ });
199
+ $[32] = t14;
200
+ $[33] = t17;
201
+ $[34] = t18;
202
+ } else {
203
+ t18 = $[34];
204
+ }
205
+ let t19;
206
+ if ($[35] !== button || $[36] !== t18) {
207
+ t19 = /*#__PURE__*/_jsxs("div", {
208
+ ref: setBox,
209
+ className: "flex h-9 shrink-0 overflow-clip rounded-full",
210
+ children: [button, t18]
211
+ });
212
+ $[35] = button;
213
+ $[36] = t18;
214
+ $[37] = t19;
215
+ } else {
216
+ t19 = $[37];
217
+ }
218
+ return t19;
219
+ }
220
+ /* The row under the box: attach, the chat's settings, the stash, the app's own control, and stop and send. */
15
221
  export function ComposerControls(t0) {
16
- const $ = _c(75);
222
+ const $ = _c(76);
17
223
  const {
18
224
  chatId,
19
225
  info,
@@ -282,55 +488,46 @@ export function ComposerControls(t0) {
282
488
  t16 = $[60];
283
489
  }
284
490
  let t17;
285
- if ($[61] !== send) {
286
- t17 = send.onContinue === null && send.visible && /*#__PURE__*/_jsx(Tooltip, {
287
- label: send.label,
288
- kbd: send.kbd,
289
- name: true,
290
- children: /*#__PURE__*/_jsx("button", {
291
- className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-accent text-accent-text hover:brightness-90 disabled:opacity-50 disabled:hover:brightness-100",
292
- disabled: send.disabled,
293
- onClick: event_0 => send.onSend(event_0.altKey),
294
- children: /*#__PURE__*/_jsx(Icon, {
295
- icon: ArrowUp,
296
- size: 16
297
- })
298
- })
491
+ if ($[61] !== send || $[62] !== writable) {
492
+ t17 = send.onContinue === null && send.visible && /*#__PURE__*/_jsx(SendButton, {
493
+ send: send,
494
+ writable: writable
299
495
  });
300
496
  $[61] = send;
301
- $[62] = t17;
497
+ $[62] = writable;
498
+ $[63] = t17;
302
499
  } else {
303
- t17 = $[62];
500
+ t17 = $[63];
304
501
  }
305
502
  let t18;
306
- if ($[63] !== t14 || $[64] !== t15 || $[65] !== t16 || $[66] !== t17) {
503
+ if ($[64] !== t14 || $[65] !== t15 || $[66] !== t16 || $[67] !== t17) {
307
504
  t18 = /*#__PURE__*/_jsxs("div", {
308
505
  className: "flex h-9 shrink-0 items-center gap-0.5 rounded-full bg-surface-hover",
309
506
  children: [t14, t15, t16, t17]
310
507
  });
311
- $[63] = t14;
312
- $[64] = t15;
313
- $[65] = t16;
314
- $[66] = t17;
315
- $[67] = t18;
508
+ $[64] = t14;
509
+ $[65] = t15;
510
+ $[66] = t16;
511
+ $[67] = t17;
512
+ $[68] = t18;
316
513
  } else {
317
- t18 = $[67];
514
+ t18 = $[68];
318
515
  }
319
516
  let t19;
320
- if ($[68] !== t10 || $[69] !== t11 || $[70] !== t12 || $[71] !== t18 || $[72] !== t3 || $[73] !== t4) {
517
+ if ($[69] !== t10 || $[70] !== t11 || $[71] !== t12 || $[72] !== t18 || $[73] !== t3 || $[74] !== t4) {
321
518
  t19 = /*#__PURE__*/_jsxs("div", {
322
519
  className: "flex items-center gap-2 pt-3 pr-3.5 pb-3.5 pl-5 @max-md/composer:gap-1.5 @max-md/composer:p-3 @max-md/composer:pt-2.5",
323
520
  children: [t3, t4, t10, t11, t12, t13, t18]
324
521
  });
325
- $[68] = t10;
326
- $[69] = t11;
327
- $[70] = t12;
328
- $[71] = t18;
329
- $[72] = t3;
330
- $[73] = t4;
331
- $[74] = t19;
332
- } else {
333
- t19 = $[74];
522
+ $[69] = t10;
523
+ $[70] = t11;
524
+ $[71] = t12;
525
+ $[72] = t18;
526
+ $[73] = t3;
527
+ $[74] = t4;
528
+ $[75] = t19;
529
+ } else {
530
+ t19 = $[75];
334
531
  }
335
532
  return t19;
336
533
  }
@@ -13,8 +13,8 @@ interface KeyHandlerInput {
13
13
  history: PromptHistory;
14
14
  noteKey(e: KeyboardEvent): void;
15
15
  toggleStash(): void;
16
- setText(next: string): void;
17
16
  submit(how: ComposerSend): void;
18
17
  }
18
+ export declare function pickInMenu(e: KeyboardEvent, menus: ComposerMenus): boolean;
19
19
  export declare function composerKeyHandler(input: KeyHandlerInput): (e: KeyboardEvent, view: EditorView) => boolean;
20
20
  export {};
@@ -37,10 +37,7 @@ function indentInFence(e, view) {
37
37
  return true;
38
38
  }
39
39
  /* The keys an open picker takes: the arrows walk it, and Tab (or Enter, outside the commands) picks. */
40
- function pickInMenu(e, {
41
- menus,
42
- setText
43
- }) {
40
+ export function pickInMenu(e, menus) {
44
41
  const {
45
42
  activeIndex
46
43
  } = menus;
@@ -49,12 +46,7 @@ function pickInMenu(e, {
49
46
  return true;
50
47
  }
51
48
  if (e.key === 'Tab') {
52
- const chosen = menus.commands[activeIndex];
53
- if (chosen.skill) {
54
- menus.chooseSkill(chosen.name);
55
- } else {
56
- setText(`/${chosen.name} `);
57
- }
49
+ menus.completeCommand(menus.commands[activeIndex]);
58
50
  return true;
59
51
  }
60
52
  }
@@ -187,7 +179,7 @@ export function composerKeyHandler(input) {
187
179
  input.toggleStash();
188
180
  return true;
189
181
  }
190
- if (pickInMenu(e, input)) {
182
+ if (pickInMenu(e, input.menus)) {
191
183
  return true;
192
184
  }
193
185
  if (e.key === 'Tab' && !e.altKey && !e.metaKey && !e.ctrlKey && indentInFence(e, view)) {
@@ -0,0 +1,4 @@
1
+ import type { ChatSendExtras } from '../../chat-client.js';
2
+ import { type Referables } from '../../chat-references.js';
3
+ import type { PromptDraft } from './use-prompt-menus.js';
4
+ export declare function promptPicks(value: PromptDraft, referables: Referables): Pick<ChatSendExtras, 'mentions' | 'skills' | 'chats' | 'references'>;
@@ -0,0 +1,14 @@
1
+ import { referenceTokens } from '../../chat-references.js';
2
+ import { presentMentions, presentReferences, presentSkills } from '../../mentions.js';
3
+ /* What a prompt still holds of what was picked in it, as a send of the composer carries it. */
4
+ export function promptPicks(value, referables) {
5
+ const text = value.text.trim();
6
+ const tokens = referenceTokens([...value.chats, ...value.references], referables.items, value.referenceNames);
7
+ return {
8
+ mentions: presentMentions(text, value.mentions),
9
+ skills: presentSkills(text, value.skills),
10
+ chats: presentReferences(text, value.chats, tokens),
11
+ // A machine that resolves only chats would drop the rest.
12
+ references: referables.chatsOnly ? [] : presentReferences(text, value.references, tokens)
13
+ };
14
+ }
@@ -1,17 +1,10 @@
1
1
  import { type RefObject } from 'react';
2
- import type { EditorState } from '@codemirror/state';
3
2
  import type { ChatInfo, ProviderCapabilities } from '@adecore/agent-contracts';
4
- import { type Referable } from '../../chat-references.js';
5
- import { type MentionQuery, type TextRange } from '../../mentions.js';
6
3
  import type { ComposerInputHandle } from '../ComposerInput.js';
7
4
  import type { ComposerDraft } from './use-composer-draft.js';
5
+ import { type PromptMenus } from './use-prompt-menus.js';
6
+ export type { ComposerCommand } from './use-prompt-menus.js';
8
7
  export declare const LOCAL_COMMANDS: string[];
9
- export interface ComposerCommand {
10
- name: string;
11
- hint: string;
12
- local: boolean;
13
- skill: boolean;
14
- }
15
8
  interface MenusInput {
16
9
  chatId: string;
17
10
  info: ChatInfo;
@@ -20,43 +13,5 @@ interface MenusInput {
20
13
  draft: ComposerDraft;
21
14
  inputRef: RefObject<ComposerInputHandle | null>;
22
15
  }
23
- export declare function useComposerMenus({ chatId, info, capabilities, providerName, draft: { draft, setDraft, setText }, inputRef }: MenusInput): {
24
- listId: string;
25
- activeIndex: number;
26
- inputAria: Record<string, string>;
27
- hasSkills: boolean;
28
- skillNames: string[];
29
- commandQuery: string | null;
30
- commands: ComposerCommand[];
31
- commandMenuOpen: boolean;
32
- skillMatches: {
33
- name: string;
34
- description: string;
35
- source: "plugin" | "project" | "user";
36
- }[];
37
- skillMenuOpen: boolean;
38
- mention: MentionQuery | null;
39
- mentionMenuOpen: boolean;
40
- mentionCount: number;
41
- files: string[];
42
- referenceMenuOpen: boolean;
43
- referenceMatches: Referable[];
44
- referables: import("../../index.js").Referables;
45
- referenceChips: {
46
- id: string;
47
- name: string;
48
- kind: import("../../index.js").ReferableKind | null;
49
- }[];
50
- setMenuIndex: import("react").Dispatch<import("react").SetStateAction<number>>;
51
- trackTriggers: (value: string, selection: TextRange, state: EditorState) => void;
52
- close: () => void;
53
- chooseMention: (path: string) => void;
54
- chooseMentionAt: (index: number) => void;
55
- chooseReference: (item: Referable) => void;
56
- chooseReferenceAt: (index: number) => void;
57
- chooseSkill: (name: string) => void;
58
- pickCommand: (command: ComposerCommand, index: number) => void;
59
- moveInMenu: (key: string, count: number) => boolean;
60
- };
61
- export type ComposerMenus = ReturnType<typeof useComposerMenus>;
62
- export {};
16
+ export declare function useComposerMenus({ chatId, info, capabilities, providerName, draft, inputRef }: MenusInput): PromptMenus;
17
+ export type ComposerMenus = PromptMenus;