@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
@@ -0,0 +1,536 @@
1
+ import { c as _c } from "react/compiler-runtime";
2
+ import { useEffect, useId, useMemo, useState } from 'react';
3
+ import { useTranslation } from 'react-i18next';
4
+ import { ensureSyntaxTree, syntaxTree } from '@codemirror/language';
5
+ import { useChatHost } from '../../../host.js';
6
+ import { useChatScope } from '../../../scope.js';
7
+ import { referenceSuggestions, referenceTokens } from '../../chat-references.js';
8
+ import { usableSlashCommands } from '../../guards.js';
9
+ import { chipRanges, findMentionQuery, findReferenceQuery, findSkillQuery, insertMention, insertReference, insertSkill, mentionPick, NO_MENTION_SEARCH, queryOutsideChips } from '../../mentions.js';
10
+ import { inCode } from './keys.js';
11
+ import { clampMenuIndex, composerMenuAria } from './menu-aria.js';
12
+ const SEARCH_DEBOUNCE_MS = 80;
13
+ // What fits above the box without turning the picker into a file tree.
14
+ const MENTION_RESULTS = 8;
15
+ const REFERENCE_RESULTS = 8;
16
+ const NO_COMMANDS = [];
17
+ function sameQuery(left, right) {
18
+ return left?.start === right?.start && left?.query === right?.query;
19
+ }
20
+ /*
21
+ * The pickers over a prompt: `/` for a command, `$` for a skill, `@` for a file and `#` for a view,
22
+ * a node or a chat. One is open at a time, and the arrow keys and the editor's ARIA attributes
23
+ * follow that one.
24
+ */
25
+ export function usePromptMenus(t0) {
26
+ const $ = _c(103);
27
+ const {
28
+ draft: t1,
29
+ inputRef,
30
+ cwd,
31
+ skills,
32
+ slashCommands,
33
+ localCommands: t2,
34
+ goals,
35
+ providerName,
36
+ referables,
37
+ ownId,
38
+ label
39
+ } = t0;
40
+ const {
41
+ draft,
42
+ setDraft,
43
+ setText
44
+ } = t1;
45
+ const localCommands = t2 === undefined ? NO_COMMANDS : t2;
46
+ const {
47
+ t
48
+ } = useTranslation("agent-chat");
49
+ const scope = useChatScope();
50
+ const {
51
+ searchFiles
52
+ } = useChatHost();
53
+ const [menuIndex, setMenuIndex] = useState(0);
54
+ const [mention, setMention] = useState(null);
55
+ const [referenceQuery, setReferenceQuery] = useState(null);
56
+ const [skillQuery, setSkillQuery] = useState(null);
57
+ const [searched, setSearched] = useState(NO_MENTION_SEARCH);
58
+ const text = draft.text;
59
+ let t3;
60
+ let t4;
61
+ if ($[0] !== cwd || $[1] !== mention || $[2] !== scope || $[3] !== searchFiles) {
62
+ t3 = () => {
63
+ if (mention === null || cwd === null) {
64
+ return;
65
+ }
66
+ let stale = false;
67
+ const search = () => {
68
+ if (searchFiles === null) {
69
+ return;
70
+ }
71
+ searchFiles(scope.id, cwd, mention.query, MENTION_RESULTS).then(files => {
72
+ if (!stale) {
73
+ setSearched({
74
+ query: mention.query,
75
+ files
76
+ });
77
+ setMenuIndex(0);
78
+ }
79
+ }).catch(_temp);
80
+ };
81
+ if (mention.query === "") {
82
+ search();
83
+ return () => {
84
+ stale = true;
85
+ };
86
+ }
87
+ const timer = setTimeout(search, SEARCH_DEBOUNCE_MS);
88
+ return () => {
89
+ stale = true;
90
+ clearTimeout(timer);
91
+ };
92
+ };
93
+ t4 = [scope, cwd, mention, searchFiles];
94
+ $[0] = cwd;
95
+ $[1] = mention;
96
+ $[2] = scope;
97
+ $[3] = searchFiles;
98
+ $[4] = t3;
99
+ $[5] = t4;
100
+ } else {
101
+ t3 = $[4];
102
+ t4 = $[5];
103
+ }
104
+ useEffect(t3, t4);
105
+ let t5;
106
+ if ($[6] !== text) {
107
+ t5 = text.startsWith("/") && !text.includes("\n") ? text.slice(1).trim().toLowerCase() : null;
108
+ $[6] = text;
109
+ $[7] = t5;
110
+ } else {
111
+ t5 = $[7];
112
+ }
113
+ const commandQuery = t5;
114
+ let t6;
115
+ bb0: {
116
+ if (commandQuery === null) {
117
+ let t7;
118
+ if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
119
+ t7 = [];
120
+ $[8] = t7;
121
+ } else {
122
+ t7 = $[8];
123
+ }
124
+ t6 = t7;
125
+ break bb0;
126
+ }
127
+ let t7;
128
+ if ($[9] !== skills) {
129
+ t7 = new Set(skills.map(_temp2));
130
+ $[9] = skills;
131
+ $[10] = t7;
132
+ } else {
133
+ t7 = $[10];
134
+ }
135
+ const known = t7;
136
+ let t8;
137
+ if ($[11] !== commandQuery || $[12] !== goals || $[13] !== known || $[14] !== localCommands || $[15] !== providerName || $[16] !== slashCommands || $[17] !== t) {
138
+ const own = localCommands.map(name => ({
139
+ name,
140
+ hint: t(`composer.commands.${name}`),
141
+ local: true,
142
+ skill: false
143
+ }));
144
+ const goal = goals ? [{
145
+ name: "goal",
146
+ hint: t("composer.commands.goal"),
147
+ local: false,
148
+ skill: false
149
+ }] : [];
150
+ const cli = usableSlashCommands([...slashCommands]).filter(name_0 => !localCommands.includes(name_0) && (!goals || name_0 !== "goal")).map(name_1 => ({
151
+ name: name_1,
152
+ hint: known.has(name_1) ? t("composer.commands.skill") : t("composer.commands.cli", {
153
+ cli: providerName ?? t("composer.commands.anyCli")
154
+ }),
155
+ local: false,
156
+ skill: known.has(name_1)
157
+ }));
158
+ t8 = [...own, ...goal, ...cli].filter(command => command.name.startsWith(commandQuery)).slice(0, 8);
159
+ $[11] = commandQuery;
160
+ $[12] = goals;
161
+ $[13] = known;
162
+ $[14] = localCommands;
163
+ $[15] = providerName;
164
+ $[16] = slashCommands;
165
+ $[17] = t;
166
+ $[18] = t8;
167
+ } else {
168
+ t8 = $[18];
169
+ }
170
+ t6 = t8;
171
+ }
172
+ const commands = t6;
173
+ let t7;
174
+ bb1: {
175
+ if (skillQuery === null) {
176
+ let t8;
177
+ if ($[19] === Symbol.for("react.memo_cache_sentinel")) {
178
+ t8 = [];
179
+ $[19] = t8;
180
+ } else {
181
+ t8 = $[19];
182
+ }
183
+ t7 = t8;
184
+ break bb1;
185
+ }
186
+ let t8;
187
+ if ($[20] !== skillQuery.query || $[21] !== skills) {
188
+ const query = skillQuery.query.toLowerCase();
189
+ t8 = skills.filter(skill_0 => skill_0.name.toLowerCase().includes(query)).slice(0, 8);
190
+ $[20] = skillQuery.query;
191
+ $[21] = skills;
192
+ $[22] = t8;
193
+ } else {
194
+ t8 = $[22];
195
+ }
196
+ t7 = t8;
197
+ }
198
+ const skillMatches = t7;
199
+ const commandMenuOpen = commandQuery !== null && commands.length > 0;
200
+ const skillMenuOpen = !commandMenuOpen && skillQuery !== null && skillMatches.length > 0;
201
+ const mentionMenuOpen = !commandMenuOpen && !skillMenuOpen && mention !== null;
202
+ const files_0 = mention === null ? [] : searched.files;
203
+ const mentionCount = files_0.length;
204
+ let t8;
205
+ if ($[23] !== referables.chatsOnly) {
206
+ t8 = item => !referables.chatsOnly || item.kind === "chat";
207
+ $[23] = referables.chatsOnly;
208
+ $[24] = t8;
209
+ } else {
210
+ t8 = $[24];
211
+ }
212
+ const offersReferences = referables.items.some(t8);
213
+ const referenceMenuOpen = !commandMenuOpen && !skillMenuOpen && !mentionMenuOpen && referenceQuery !== null && offersReferences;
214
+ const excluded = ownId === undefined ? [...draft.chats, ...draft.references] : [ownId, ...draft.chats, ...draft.references];
215
+ const referenceMatches = referenceMenuOpen ? referenceSuggestions(referables, referenceQuery.query, excluded, REFERENCE_RESULTS) : [];
216
+ let t9;
217
+ if ($[25] !== draft.chats || $[26] !== draft.referenceNames || $[27] !== draft.references || $[28] !== referables.items) {
218
+ let t10;
219
+ if ($[30] !== referables.items) {
220
+ t10 = token => ({
221
+ ...token,
222
+ kind: referables.items.find(item_0 => item_0.id === token.id)?.kind ?? null
223
+ });
224
+ $[30] = referables.items;
225
+ $[31] = t10;
226
+ } else {
227
+ t10 = $[31];
228
+ }
229
+ t9 = referenceTokens([...draft.chats, ...draft.references], referables.items, draft.referenceNames).map(t10);
230
+ $[25] = draft.chats;
231
+ $[26] = draft.referenceNames;
232
+ $[27] = draft.references;
233
+ $[28] = referables.items;
234
+ $[29] = t9;
235
+ } else {
236
+ t9 = $[29];
237
+ }
238
+ const referenceChips = t9;
239
+ const listId = useId();
240
+ const menuOpen = commandMenuOpen || skillMenuOpen || mentionMenuOpen || referenceMenuOpen;
241
+ const menuCount = commandMenuOpen ? commands.length : skillMenuOpen ? skillMatches.length : mentionMenuOpen ? mentionCount : referenceMatches.length;
242
+ const activeIndex = clampMenuIndex(menuIndex, menuCount);
243
+ const inputAria = composerMenuAria({
244
+ label,
245
+ listId,
246
+ open: menuOpen,
247
+ activeIndex,
248
+ count: menuCount
249
+ });
250
+ let t10;
251
+ if ($[32] !== cwd || $[33] !== draft.mentions || $[34] !== draft.skills || $[35] !== referenceChips) {
252
+ t10 = (value, selection, state) => {
253
+ const empty = selection.from === selection.to;
254
+ const tree = empty ? ensureSyntaxTree(state, selection.from, 50) ?? syntaxTree(state) : null;
255
+ const caret = tree !== null && !inCode(tree, value, selection.from) ? selection.from : null;
256
+ const chips = caret === null ? [] : chipRanges(value, draft.mentions, draft.skills, [], referenceChips);
257
+ const skill_1 = caret === null ? null : queryOutsideChips(findSkillQuery(value, caret), chips);
258
+ setSkillQuery(current => sameQuery(current, skill_1) ? current : skill_1);
259
+ const next = caret === null || cwd === null ? null : queryOutsideChips(findMentionQuery(value, caret), chips);
260
+ setMention(current_0 => sameQuery(current_0, next) ? current_0 : next);
261
+ const reference = caret === null ? null : queryOutsideChips(findReferenceQuery(value, caret), chips);
262
+ setReferenceQuery(current_1 => sameQuery(current_1, reference) ? current_1 : reference);
263
+ };
264
+ $[32] = cwd;
265
+ $[33] = draft.mentions;
266
+ $[34] = draft.skills;
267
+ $[35] = referenceChips;
268
+ $[36] = t10;
269
+ } else {
270
+ t10 = $[36];
271
+ }
272
+ const trackTriggers = t10;
273
+ let t11;
274
+ if ($[37] !== inputRef) {
275
+ t11 = caret_0 => {
276
+ requestAnimationFrame(() => inputRef.current?.setCaret(caret_0));
277
+ };
278
+ $[37] = inputRef;
279
+ $[38] = t11;
280
+ } else {
281
+ t11 = $[38];
282
+ }
283
+ const moveCaret = t11;
284
+ let t12;
285
+ if ($[39] === Symbol.for("react.memo_cache_sentinel")) {
286
+ t12 = () => {
287
+ setMention(null);
288
+ setSkillQuery(null);
289
+ setReferenceQuery(null);
290
+ };
291
+ $[39] = t12;
292
+ } else {
293
+ t12 = $[39];
294
+ }
295
+ const close = t12;
296
+ let t13;
297
+ if ($[40] !== draft.mentions || $[41] !== mention || $[42] !== moveCaret || $[43] !== setText || $[44] !== text) {
298
+ t13 = path => {
299
+ if (!mention) {
300
+ return;
301
+ }
302
+ const result = insertMention(text, mention, path);
303
+ setText(result.text, draft.mentions.includes(path) ? draft.mentions : [...draft.mentions, path]);
304
+ setMention(null);
305
+ moveCaret(result.caret);
306
+ };
307
+ $[40] = draft.mentions;
308
+ $[41] = mention;
309
+ $[42] = moveCaret;
310
+ $[43] = setText;
311
+ $[44] = text;
312
+ $[45] = t13;
313
+ } else {
314
+ t13 = $[45];
315
+ }
316
+ const chooseMention = t13;
317
+ let t14;
318
+ if ($[46] !== chooseMention || $[47] !== mention || $[48] !== searched) {
319
+ t14 = index => {
320
+ const path_0 = mention === null ? null : mentionPick(index, searched, mention.query);
321
+ if (path_0 !== null) {
322
+ chooseMention(path_0);
323
+ }
324
+ };
325
+ $[46] = chooseMention;
326
+ $[47] = mention;
327
+ $[48] = searched;
328
+ $[49] = t14;
329
+ } else {
330
+ t14 = $[49];
331
+ }
332
+ const chooseMentionAt = t14;
333
+ let t15;
334
+ if ($[50] !== moveCaret || $[51] !== referenceQuery || $[52] !== setDraft || $[53] !== text) {
335
+ t15 = item_1 => {
336
+ if (!referenceQuery) {
337
+ return;
338
+ }
339
+ const result_0 = insertReference(text, referenceQuery, item_1.name);
340
+ const chat = item_1.kind === "chat";
341
+ const add = ids => ids.includes(item_1.id) ? ids : [...ids, item_1.id];
342
+ setDraft(current_2 => ({
343
+ ...current_2,
344
+ text: result_0.text,
345
+ chats: chat ? add(current_2.chats) : current_2.chats,
346
+ references: chat ? current_2.references : add(current_2.references),
347
+ referenceNames: {
348
+ ...current_2.referenceNames,
349
+ [item_1.id]: item_1.name
350
+ }
351
+ }));
352
+ setReferenceQuery(null);
353
+ moveCaret(result_0.caret);
354
+ };
355
+ $[50] = moveCaret;
356
+ $[51] = referenceQuery;
357
+ $[52] = setDraft;
358
+ $[53] = text;
359
+ $[54] = t15;
360
+ } else {
361
+ t15 = $[54];
362
+ }
363
+ const chooseReference = t15;
364
+ let t16;
365
+ if ($[55] !== chooseReference || $[56] !== referenceMatches) {
366
+ t16 = index_0 => {
367
+ const item_2 = referenceMatches[index_0] ?? referenceMatches[0];
368
+ if (item_2 !== undefined) {
369
+ chooseReference(item_2);
370
+ }
371
+ };
372
+ $[55] = chooseReference;
373
+ $[56] = referenceMatches;
374
+ $[57] = t16;
375
+ } else {
376
+ t16 = $[57];
377
+ }
378
+ const chooseReferenceAt = t16;
379
+ let t17;
380
+ if ($[58] !== draft.mentions || $[59] !== draft.skills || $[60] !== moveCaret || $[61] !== setText || $[62] !== skillQuery || $[63] !== text) {
381
+ t17 = name_2 => {
382
+ const result_1 = skillQuery ? insertSkill(text, skillQuery, name_2) : {
383
+ text: `$${name_2} `,
384
+ caret: name_2.length + 2
385
+ };
386
+ setText(result_1.text, draft.mentions, draft.skills.includes(name_2) ? draft.skills : [...draft.skills, name_2]);
387
+ setSkillQuery(null);
388
+ moveCaret(result_1.caret);
389
+ };
390
+ $[58] = draft.mentions;
391
+ $[59] = draft.skills;
392
+ $[60] = moveCaret;
393
+ $[61] = setText;
394
+ $[62] = skillQuery;
395
+ $[63] = text;
396
+ $[64] = t17;
397
+ } else {
398
+ t17 = $[64];
399
+ }
400
+ const chooseSkill = t17;
401
+ let t18;
402
+ if ($[65] !== chooseSkill || $[66] !== inputRef || $[67] !== setText) {
403
+ t18 = (command_0, index_1) => {
404
+ setMenuIndex(index_1);
405
+ if (command_0.skill) {
406
+ chooseSkill(command_0.name);
407
+ return;
408
+ }
409
+ setText(`/${command_0.name}`);
410
+ inputRef.current?.focus();
411
+ };
412
+ $[65] = chooseSkill;
413
+ $[66] = inputRef;
414
+ $[67] = setText;
415
+ $[68] = t18;
416
+ } else {
417
+ t18 = $[68];
418
+ }
419
+ const pickCommand = t18;
420
+ let t19;
421
+ if ($[69] !== chooseSkill || $[70] !== setText) {
422
+ t19 = command_1 => {
423
+ if (command_1.skill) {
424
+ chooseSkill(command_1.name);
425
+ return;
426
+ }
427
+ setText(`/${command_1.name} `);
428
+ };
429
+ $[69] = chooseSkill;
430
+ $[70] = setText;
431
+ $[71] = t19;
432
+ } else {
433
+ t19 = $[71];
434
+ }
435
+ const completeCommand = t19;
436
+ let t20;
437
+ if ($[72] === Symbol.for("react.memo_cache_sentinel")) {
438
+ t20 = (key, count) => {
439
+ if (key === "ArrowDown") {
440
+ setMenuIndex(i => (i + 1) % count);
441
+ return true;
442
+ }
443
+ if (key === "ArrowUp") {
444
+ setMenuIndex(i_0 => (i_0 - 1 + count) % count);
445
+ return true;
446
+ }
447
+ return false;
448
+ };
449
+ $[72] = t20;
450
+ } else {
451
+ t20 = $[72];
452
+ }
453
+ const moveInMenu = t20;
454
+ const t21 = skills.length > 0;
455
+ let t22;
456
+ if ($[73] !== skills) {
457
+ t22 = skills.map(_temp3);
458
+ $[73] = skills;
459
+ $[74] = t22;
460
+ } else {
461
+ t22 = $[74];
462
+ }
463
+ let t23;
464
+ if ($[75] !== activeIndex || $[76] !== chooseMention || $[77] !== chooseMentionAt || $[78] !== chooseReference || $[79] !== chooseReferenceAt || $[80] !== chooseSkill || $[81] !== commandMenuOpen || $[82] !== commandQuery || $[83] !== commands || $[84] !== completeCommand || $[85] !== files_0 || $[86] !== inputAria || $[87] !== listId || $[88] !== mention || $[89] !== mentionCount || $[90] !== mentionMenuOpen || $[91] !== menuOpen || $[92] !== pickCommand || $[93] !== referables || $[94] !== referenceChips || $[95] !== referenceMatches || $[96] !== referenceMenuOpen || $[97] !== skillMatches || $[98] !== skillMenuOpen || $[99] !== t21 || $[100] !== t22 || $[101] !== trackTriggers) {
465
+ t23 = {
466
+ listId,
467
+ activeIndex,
468
+ inputAria,
469
+ menuOpen,
470
+ hasSkills: t21,
471
+ skillNames: t22,
472
+ commandQuery,
473
+ commands,
474
+ commandMenuOpen,
475
+ skillMatches,
476
+ skillMenuOpen,
477
+ mention,
478
+ mentionMenuOpen,
479
+ mentionCount,
480
+ files: files_0,
481
+ referenceMenuOpen,
482
+ referenceMatches,
483
+ referables,
484
+ referenceChips,
485
+ setMenuIndex,
486
+ trackTriggers,
487
+ close,
488
+ chooseMention,
489
+ chooseMentionAt,
490
+ chooseReference,
491
+ chooseReferenceAt,
492
+ chooseSkill,
493
+ pickCommand,
494
+ completeCommand,
495
+ moveInMenu
496
+ };
497
+ $[75] = activeIndex;
498
+ $[76] = chooseMention;
499
+ $[77] = chooseMentionAt;
500
+ $[78] = chooseReference;
501
+ $[79] = chooseReferenceAt;
502
+ $[80] = chooseSkill;
503
+ $[81] = commandMenuOpen;
504
+ $[82] = commandQuery;
505
+ $[83] = commands;
506
+ $[84] = completeCommand;
507
+ $[85] = files_0;
508
+ $[86] = inputAria;
509
+ $[87] = listId;
510
+ $[88] = mention;
511
+ $[89] = mentionCount;
512
+ $[90] = mentionMenuOpen;
513
+ $[91] = menuOpen;
514
+ $[92] = pickCommand;
515
+ $[93] = referables;
516
+ $[94] = referenceChips;
517
+ $[95] = referenceMatches;
518
+ $[96] = referenceMenuOpen;
519
+ $[97] = skillMatches;
520
+ $[98] = skillMenuOpen;
521
+ $[99] = t21;
522
+ $[100] = t22;
523
+ $[101] = trackTriggers;
524
+ $[102] = t23;
525
+ } else {
526
+ t23 = $[102];
527
+ }
528
+ return t23;
529
+ }
530
+ function _temp3(skill_2) {
531
+ return skill_2.name;
532
+ }
533
+ function _temp2(skill) {
534
+ return skill.name;
535
+ }
536
+ function _temp() {}
@@ -13,6 +13,9 @@ export { ImageThumb, type ImageThumbProps } from './ImageView.js';
13
13
  export { LimitDock, LimitPill } from './LimitState.js';
14
14
  export { ReplyMarkdown, MessageMarkdown, Markdown } from './Markdown.js';
15
15
  export { ModelPicker } from './Pickers.js';
16
+ export { PromptEditor } from './PromptEditor.js';
17
+ export { promptPicks } from './composer/prompt-picks.js';
18
+ export type { PromptDraft } from './composer/use-prompt-menus.js';
16
19
  export { ResumeCompactionDock } from './ResumeCompactionDock.js';
17
20
  export { SubagentTitleCrumb, SubagentBreadcrumb } from './SubagentControls.js';
18
21
  export { SubagentInfo } from './SubagentInfo.js';
@@ -14,6 +14,8 @@ export { ImageThumb } from './ImageView.js';
14
14
  export { LimitDock, LimitPill } from './LimitState.js';
15
15
  export { ReplyMarkdown, MessageMarkdown, Markdown } from './Markdown.js';
16
16
  export { ModelPicker } from './Pickers.js';
17
+ export { PromptEditor } from './PromptEditor.js';
18
+ export { promptPicks } from './composer/prompt-picks.js';
17
19
  export { ResumeCompactionDock } from './ResumeCompactionDock.js';
18
20
  export { SubagentTitleCrumb, SubagentBreadcrumb } from './SubagentControls.js';
19
21
  export { SubagentInfo } from './SubagentInfo.js';
@@ -1,6 +1,6 @@
1
1
  import type { ProviderPlatform } from '@adecore/agent-contracts';
2
2
  import { type Referables } from './chat/chat-references.js';
3
- import { type ChatHost, type CommandLook } from './host.js';
3
+ import { type ChatHost, type CommandLook, type ComposerSendAction } from './host.js';
4
4
  export declare function useHostCodeMode(): 'light' | 'dark';
5
5
  export declare function useHostCodeThemes(): {
6
6
  light: string;
@@ -25,6 +25,7 @@ export declare function useHostHidesFolder(...args: Parameters<ChatHost['useHide
25
25
  export declare function useHostWelcome(...args: Parameters<ChatHost['useWelcome']>): ReturnType<ChatHost['useWelcome']>;
26
26
  export declare function useHostResumeAtReset(...args: Parameters<ChatHost['useResumeAtReset']>): ReturnType<ChatHost['useResumeAtReset']>;
27
27
  export declare function useHostComposerPlaceholder(...args: Parameters<ChatHost['useComposerPlaceholder']>): ReturnType<ChatHost['useComposerPlaceholder']>;
28
+ export declare function useHostComposerSendActions(scopeId: string, chatId: string): readonly ComposerSendAction[];
28
29
  export declare function useHostThreadCards(...args: Parameters<ChatHost['useThreadCards']>): ReturnType<ChatHost['useThreadCards']>;
29
30
  export declare function useHostReplyAuthor(...args: Parameters<ChatHost['useReplyAuthor']>): ReturnType<ChatHost['useReplyAuthor']>;
30
31
  export declare function useHostMapSource(maps: NonNullable<ChatHost['maps']>, scopeId: string): ReturnType<NonNullable<ChatHost['maps']>['useSource']>;
@@ -71,6 +71,12 @@ export function useHostResumeAtReset(...args) {
71
71
  export function useHostComposerPlaceholder(...args) {
72
72
  return useChatHost().useComposerPlaceholder(...args);
73
73
  }
74
+ const NO_SEND_ACTIONS = [];
75
+ const noSendActions = () => NO_SEND_ACTIONS;
76
+ export function useHostComposerSendActions(scopeId, chatId) {
77
+ const useSendActions = useChatHost().useComposerSendActions ?? noSendActions;
78
+ return useSendActions(scopeId, chatId);
79
+ }
74
80
  export function useHostThreadCards(...args) {
75
81
  return useChatHost().useThreadCards(...args);
76
82
  }
package/dist/host.d.ts CHANGED
@@ -4,7 +4,7 @@ import type { EditorView } from '@codemirror/view';
4
4
  import type { Highlighter, ThemeRegistration } from 'shiki';
5
5
  import type { LucideIcon } from 'lucide-react';
6
6
  import type { EditorEngine } from '@adecore/editor';
7
- import type { AgentKind, ChatAttachment, ChatCheckpointDiff, ChatConfigurePayload, ChatGoalAction, ChatItem, ChatSubagentItem, ChatUiChoicePayload, ChatUiQueryPayload, ChatUiQueryReading, ChatUiLinkPayload, ChatUiLinkReading, ChatVisual, ProviderPlatform } from '@adecore/agent-contracts';
7
+ import type { AgentKind, ChatAttachment, ChatCheckpointDiff, ChatConfigurePayload, ChatGoalAction, ChatItem, ChatSubagentItem, ChatUiChoicePayload, ChatUiQueryPayload, ChatUiQueryReading, ChatUiLinkPayload, ChatUiLinkReading, ChatVisual, ModelSelection, ProviderPlatform, RuntimeMode } from '@adecore/agent-contracts';
8
8
  import type { Referables } from './chat/chat-references.js';
9
9
  import type { TimelineRow } from './chat/logic/timeline.js';
10
10
  import type { FindReveal } from './chat/ui/find-reveal.js';
@@ -110,6 +110,21 @@ export interface ComposerSlotProps {
110
110
  disabled: boolean;
111
111
  insert(text: string): void;
112
112
  }
113
+ export interface ComposerSendDraft {
114
+ scopeId: string;
115
+ chatId: string;
116
+ text: string;
117
+ provider: AgentKind;
118
+ selection: ModelSelection;
119
+ runtimeMode: RuntimeMode;
120
+ }
121
+ export interface ComposerSendAction {
122
+ id: string;
123
+ label: string;
124
+ icon?: LucideIcon;
125
+ disabled?: boolean;
126
+ run(draft: ComposerSendDraft): void;
127
+ }
113
128
  export interface SubagentSlotProps {
114
129
  chatId: string;
115
130
  items: readonly ChatSubagentItem[];
@@ -290,6 +305,7 @@ export interface ChatHost {
290
305
  useResumeAtReset(scopeId: string): boolean;
291
306
  useComposerPlaceholder(scopeId: string, chatId: string): string | null;
292
307
  ComposerSlot: ComponentType<ComposerSlotProps> | null;
308
+ useComposerSendActions?(scopeId: string, chatId: string): readonly ComposerSendAction[];
293
309
  SubagentSlot: ComponentType<SubagentSlotProps> | null;
294
310
  useThreadCards(scopeId: string, chatId: string): readonly ThreadCard[];
295
311
  useReplyAuthor(scopeId: string, chatId: string): ReplyAuthor | null;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { type ChatActions, type FileRef, type ShellCodeBlockContext, type ChatPlace, type SubagentTask, type TimelineFindOptions, type TimelineFind, type ComposerDictationProps, type ComposerSlotProps, type SubagentSlotProps, type ThreadCard, type VisualHost, type HostMenuAction, type ReplyAuthor, type ChatHost, type UiMapSource, type UiModelViewProps, type CommandLook, type CommandLookMatch, type CommandName, ChatHostProvider, useChatHost, type AccentChoice, type ChatToast, type TextareaProps, type ResourceUrl } from './host.js';
1
+ export { type ChatActions, type FileRef, type ShellCodeBlockContext, type ChatPlace, type SubagentTask, type TimelineFindOptions, type TimelineFind, type ComposerDictationProps, type ComposerSlotProps, type ComposerSendAction, type ComposerSendDraft, type SubagentSlotProps, type ThreadCard, type VisualHost, type HostMenuAction, type ReplyAuthor, type ChatHost, type UiMapSource, type UiModelViewProps, type CommandLook, type CommandLookMatch, type CommandName, ChatHostProvider, useChatHost, type AccentChoice, type ChatToast, type TextareaProps, type ResourceUrl } from './host.js';
2
2
  export { type ChatScope, ChatScopeContext, useChatScope } from './scope.js';
3
3
  export { type ChatRequestMap, type ChatEventMap, type ChatTransportStatus, type ChatTransport, ChatTransportError, errorCode, isConnectionError } from './transport.js';
4
4
  export { portTransport, type PortTransport } from './port-transport.js';
@@ -391,6 +391,7 @@ declare const _default: {
391
391
  continue: string;
392
392
  continueHint: string;
393
393
  send: string;
394
+ sendActions: string;
394
395
  clear: {
395
396
  title: string;
396
397
  description: string;
@@ -391,6 +391,7 @@ export default {
391
391
  continue: 'Continue',
392
392
  continueHint: 'Continue the stopped turn',
393
393
  send: 'Send',
394
+ sendActions: 'More send options',
394
395
  clear: {
395
396
  title: 'Clear thread?',
396
397
  description: 'A turn is running.',
@@ -391,6 +391,7 @@ declare const _default: {
391
391
  continue: string;
392
392
  continueHint: string;
393
393
  send: string;
394
+ sendActions: string;
394
395
  clear: {
395
396
  title: string;
396
397
  description: string;
@@ -391,6 +391,7 @@ export default {
391
391
  continue: 'Doorgaan',
392
392
  continueHint: 'Ga verder met de gestopte beurt',
393
393
  send: 'Versturen',
394
+ sendActions: 'Meer verzendopties',
394
395
  clear: {
395
396
  title: 'Thread wissen?',
396
397
  description: 'Er loopt een turn.',
@@ -1,5 +1,6 @@
1
1
  export { AccountDot } from '../agents/AccountDot.js';
2
2
  export { AgentIcon } from '../agents/AgentIcon.js';
3
+ export { AgentModelLabel } from '../agents/AgentModelLabel.js';
3
4
  export { ModelOptionControl } from '../agents/ModelOptionControl.js';
4
5
  export { ProviderLogo } from '../agents/ProviderLogo.js';
5
6
  export { type AccountEntry, accountsOfKind, ACCOUNT_TONE_CLASSES, accountStatusLine, canContinueOn, type AccountTone } from '../agents/accounts.js';
@@ -1,6 +1,7 @@
1
1
  // Public API: exports.test.ts snapshots this list, so a name added or dropped here is an API change.
2
2
  export { AccountDot } from '../agents/AccountDot.js';
3
3
  export { AgentIcon } from '../agents/AgentIcon.js';
4
+ export { AgentModelLabel } from '../agents/AgentModelLabel.js';
4
5
  export { ModelOptionControl } from '../agents/ModelOptionControl.js';
5
6
  export { ProviderLogo } from '../agents/ProviderLogo.js';
6
7
  export { accountsOfKind, ACCOUNT_TONE_CLASSES, accountStatusLine, canContinueOn } from '../agents/accounts.js';