@adecore/agents-react 0.37.2 → 0.38.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 (115) hide show
  1. package/dist/chat/chat-client.d.ts +1 -0
  2. package/dist/chat/chat-client.js +2 -1
  3. package/dist/chat/chat-references.d.ts +16 -1
  4. package/dist/chat/chat-references.js +29 -3
  5. package/dist/chat/drafts.d.ts +2 -0
  6. package/dist/chat/drafts.js +21 -5
  7. package/dist/chat/index.d.ts +1 -1
  8. package/dist/chat/logic/visual-height.d.ts +1 -0
  9. package/dist/chat/logic/visual-height.js +1 -1
  10. package/dist/chat/mentions.d.ts +31 -14
  11. package/dist/chat/mentions.js +186 -41
  12. package/dist/chat/stash.d.ts +1 -0
  13. package/dist/chat/stash.js +4 -2
  14. package/dist/chat/ui/Composer.js +438 -429
  15. package/dist/chat/ui/ComposerInput.d.ts +1 -0
  16. package/dist/chat/ui/ComposerInput.js +2 -0
  17. package/dist/chat/ui/HostMenuItems.d.ts +4 -0
  18. package/dist/chat/ui/HostMenuItems.js +15 -0
  19. package/dist/chat/ui/Markdown.d.ts +3 -1
  20. package/dist/chat/ui/Markdown.js +194 -120
  21. package/dist/chat/ui/MessageActions.js +70 -66
  22. package/dist/chat/ui/ReferenceChip.d.ts +15 -0
  23. package/dist/chat/ui/ReferenceChip.js +255 -0
  24. package/dist/chat/ui/Timeline.js +52 -29
  25. package/dist/chat/ui/TimelineMenu.js +84 -78
  26. package/dist/chat/ui/VisualFrame.d.ts +8 -0
  27. package/dist/chat/ui/VisualFrame.js +217 -115
  28. package/dist/chat/ui/chip-clipboard.d.ts +9 -0
  29. package/dist/chat/ui/chip-clipboard.js +105 -0
  30. package/dist/chat/ui/chips.d.ts +5 -0
  31. package/dist/chat/ui/chips.js +15 -1
  32. package/dist/chat/ui/composer/ComposerMenu.js +140 -79
  33. package/dist/chat/ui/composer/DraftParts.d.ts +0 -4
  34. package/dist/chat/ui/composer/DraftParts.js +0 -41
  35. package/dist/chat/ui/composer/chip-paste.d.ts +15 -0
  36. package/dist/chat/ui/composer/chip-paste.js +104 -0
  37. package/dist/chat/ui/composer/chips.d.ts +5 -0
  38. package/dist/chat/ui/composer/chips.js +59 -9
  39. package/dist/chat/ui/composer/key-handler.js +9 -0
  40. package/dist/chat/ui/composer/use-composer-draft.d.ts +0 -1
  41. package/dist/chat/ui/composer/use-composer-draft.js +2 -10
  42. package/dist/chat/ui/composer/use-composer-menus.d.ts +12 -2
  43. package/dist/chat/ui/composer/use-composer-menus.js +192 -149
  44. package/dist/chat/ui/composer/use-composer-submit.js +17 -12
  45. package/dist/chat/ui/composer/use-draft-files.d.ts +7 -1
  46. package/dist/chat/ui/composer/use-draft-files.js +90 -58
  47. package/dist/chat/ui/composer/use-take-back.js +2 -1
  48. package/dist/chat/ui/index.d.ts +1 -1
  49. package/dist/chat/ui/index.js +1 -1
  50. package/dist/chat/ui/reference-icons.d.ts +3 -0
  51. package/dist/chat/ui/reference-icons.js +15 -0
  52. package/dist/chat/ui/reference-lookup.d.ts +7 -0
  53. package/dist/chat/ui/reference-lookup.js +6 -0
  54. package/dist/chat/ui/rehype-chips.d.ts +8 -1
  55. package/dist/chat/ui/rehype-chips.js +35 -11
  56. package/dist/chat/ui/rows/GeneratedImageRow.js +8 -4
  57. package/dist/chat/ui/rows/MessageRows.js +218 -158
  58. package/dist/chat/ui/rows/VisualRow.js +184 -142
  59. package/dist/chat/ui/rows/row-rhythm.js +6 -4
  60. package/dist/chat/ui/thread-references.d.ts +4 -0
  61. package/dist/chat/ui/thread-references.js +78 -0
  62. package/dist/host-hooks.d.ts +2 -0
  63. package/dist/host-hooks.js +7 -0
  64. package/dist/host.d.ts +14 -1
  65. package/dist/index.d.ts +1 -1
  66. package/dist/locales/en/agent-chat.d.ts +20 -3
  67. package/dist/locales/en/agent-chat.js +24 -7
  68. package/dist/locales/nl/agent-chat.d.ts +20 -3
  69. package/dist/locales/nl/agent-chat.js +24 -7
  70. package/package.json +8 -8
  71. package/src/chat/chat-client.ts +4 -1
  72. package/src/chat/chat-references.ts +44 -3
  73. package/src/chat/drafts.ts +24 -6
  74. package/src/chat/index.ts +1 -1
  75. package/src/chat/logic/visual-height.ts +1 -1
  76. package/src/chat/mentions.ts +202 -36
  77. package/src/chat/stash.ts +6 -2
  78. package/src/chat/ui/Composer.tsx +14 -4
  79. package/src/chat/ui/ComposerInput.tsx +4 -0
  80. package/src/chat/ui/HostMenuItems.tsx +11 -0
  81. package/src/chat/ui/Markdown.tsx +57 -25
  82. package/src/chat/ui/MessageActions.tsx +5 -2
  83. package/src/chat/ui/ReferenceChip.tsx +74 -0
  84. package/src/chat/ui/Timeline.tsx +24 -2
  85. package/src/chat/ui/TimelineMenu.tsx +7 -3
  86. package/src/chat/ui/VisualFrame.tsx +68 -21
  87. package/src/chat/ui/chip-clipboard.ts +115 -0
  88. package/src/chat/ui/chips.ts +20 -1
  89. package/src/chat/ui/composer/ComposerMenu.tsx +53 -37
  90. package/src/chat/ui/composer/DraftParts.tsx +0 -12
  91. package/src/chat/ui/composer/chip-paste.ts +122 -0
  92. package/src/chat/ui/composer/chips.ts +60 -10
  93. package/src/chat/ui/composer/key-handler.ts +9 -0
  94. package/src/chat/ui/composer/use-composer-draft.ts +1 -7
  95. package/src/chat/ui/composer/use-composer-menus.ts +68 -29
  96. package/src/chat/ui/composer/use-composer-submit.ts +13 -6
  97. package/src/chat/ui/composer/use-draft-files.ts +39 -5
  98. package/src/chat/ui/composer/use-take-back.ts +2 -1
  99. package/src/chat/ui/index.ts +1 -1
  100. package/src/chat/ui/reference-icons.ts +17 -0
  101. package/src/chat/ui/reference-lookup.ts +13 -0
  102. package/src/chat/ui/rehype-chips.ts +38 -13
  103. package/src/chat/ui/rows/GeneratedImageRow.tsx +9 -4
  104. package/src/chat/ui/rows/MessageRows.tsx +88 -64
  105. package/src/chat/ui/rows/VisualRow.tsx +5 -1
  106. package/src/chat/ui/rows/row-rhythm.ts +6 -4
  107. package/src/chat/ui/thread-references.ts +47 -0
  108. package/src/host-hooks.ts +9 -0
  109. package/src/host.ts +24 -1
  110. package/src/index.ts +1 -0
  111. package/src/locales/en/agent-chat.ts +24 -7
  112. package/src/locales/nl/agent-chat.ts +24 -7
  113. package/dist/chat/ui/ChatReferenceChip.d.ts +0 -4
  114. package/dist/chat/ui/ChatReferenceChip.js +0 -110
  115. package/src/chat/ui/ChatReferenceChip.tsx +0 -26
@@ -16,10 +16,9 @@ export default {
16
16
  unreadable: 'Could not read {{name}}',
17
17
  unreadableThumbnail: 'Could not read the thumbnail'
18
18
  },
19
- chatReference: {
20
- gone: 'Chat not in this project',
21
- untitled: 'Untitled chat',
22
- remove: 'Remove {{title}}'
19
+ references: {
20
+ gone: 'Not in this project',
21
+ untitled: 'Untitled'
23
22
  },
24
23
  fork: {
25
24
  refusal: {
@@ -304,7 +303,8 @@ export default {
304
303
  menu: {
305
304
  commands: 'Commands',
306
305
  skills: 'Skills',
307
- mentions: 'Mentions'
306
+ mentions: 'Mentions',
307
+ references: 'Views and nodes'
308
308
  },
309
309
  held: {
310
310
  question: 'Question waiting. Opens when you pause typing.',
@@ -349,10 +349,27 @@ export default {
349
349
  mentions: {
350
350
  here: 'Files in this folder',
351
351
  files: 'Files',
352
- chats: 'Chats in this project',
353
- noMatch: 'No files or chats match',
352
+ noMatch: 'No files match',
354
353
  empty: 'No files here'
355
354
  },
355
+ references: {
356
+ canvas: 'On this canvas',
357
+ views: 'Views',
358
+ noMatch: 'No view or node matches',
359
+ kinds: {
360
+ canvas: 'canvas',
361
+ chat: 'chat',
362
+ terminal: 'terminal',
363
+ note: 'note',
364
+ text: 'text',
365
+ drawing: 'drawing',
366
+ diagram: 'diagram',
367
+ browser: 'browser',
368
+ device: 'device',
369
+ file: 'file',
370
+ database: 'table'
371
+ }
372
+ },
356
373
  queue: {
357
374
  attachments_one: '{{count}} attachment',
358
375
  attachments_other: '{{count}} attachments',
@@ -16,10 +16,9 @@ declare const _default: {
16
16
  unreadable: string;
17
17
  unreadableThumbnail: string;
18
18
  };
19
- chatReference: {
19
+ references: {
20
20
  gone: string;
21
21
  untitled: string;
22
- remove: string;
23
22
  };
24
23
  fork: {
25
24
  refusal: {
@@ -305,6 +304,7 @@ declare const _default: {
305
304
  commands: string;
306
305
  skills: string;
307
306
  mentions: string;
307
+ references: string;
308
308
  };
309
309
  held: {
310
310
  question: string;
@@ -349,10 +349,27 @@ declare const _default: {
349
349
  mentions: {
350
350
  here: string;
351
351
  files: string;
352
- chats: string;
353
352
  noMatch: string;
354
353
  empty: string;
355
354
  };
355
+ references: {
356
+ canvas: string;
357
+ views: string;
358
+ noMatch: string;
359
+ kinds: {
360
+ canvas: string;
361
+ chat: string;
362
+ terminal: string;
363
+ note: string;
364
+ text: string;
365
+ drawing: string;
366
+ diagram: string;
367
+ browser: string;
368
+ device: string;
369
+ file: string;
370
+ database: string;
371
+ };
372
+ };
356
373
  queue: {
357
374
  attachments_one: string;
358
375
  attachments_other: string;
@@ -16,10 +16,9 @@ export default {
16
16
  unreadable: 'Kon {{name}} niet lezen',
17
17
  unreadableThumbnail: 'Kon de miniatuur niet lezen'
18
18
  },
19
- chatReference: {
20
- gone: 'Chat niet in dit project',
21
- untitled: 'Naamloze chat',
22
- remove: '{{title}} verwijderen'
19
+ references: {
20
+ gone: 'Niet in dit project',
21
+ untitled: 'Naamloos'
23
22
  },
24
23
  fork: {
25
24
  refusal: {
@@ -304,7 +303,8 @@ export default {
304
303
  menu: {
305
304
  commands: "Commando's",
306
305
  skills: 'Skills',
307
- mentions: 'Vermeldingen'
306
+ mentions: 'Vermeldingen',
307
+ references: 'Views en nodes'
308
308
  },
309
309
  held: {
310
310
  question: 'Er wacht een vraag. Opent zodra je stopt met typen.',
@@ -349,10 +349,27 @@ export default {
349
349
  mentions: {
350
350
  here: 'Bestanden in deze map',
351
351
  files: 'Bestanden',
352
- chats: 'Chats in dit project',
353
- noMatch: 'Geen bestanden of chats gevonden',
352
+ noMatch: 'Geen bestanden gevonden',
354
353
  empty: 'Hier staan geen bestanden'
355
354
  },
355
+ references: {
356
+ canvas: 'Op dit canvas',
357
+ views: 'Views',
358
+ noMatch: 'Geen view of node gevonden',
359
+ kinds: {
360
+ canvas: 'canvas',
361
+ chat: 'chat',
362
+ terminal: 'terminal',
363
+ note: 'notitie',
364
+ text: 'tekst',
365
+ drawing: 'tekening',
366
+ diagram: 'diagram',
367
+ browser: 'browser',
368
+ device: 'apparaat',
369
+ file: 'bestand',
370
+ database: 'tabel'
371
+ }
372
+ },
356
373
  queue: {
357
374
  attachments_one: '{{count}} bijlage',
358
375
  attachments_other: '{{count}} bijlagen',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adecore/agents-react",
3
- "version": "0.37.2",
3
+ "version": "0.38.0",
4
4
  "description": "React agent chat threads, composers, approvals, provider accounts and usage views.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -67,11 +67,11 @@
67
67
  "test:visuals": "bun --config=integration.bunfig.toml --conditions=source test ./src/chat/visual-viewport.integration.test.ts"
68
68
  },
69
69
  "dependencies": {
70
- "@adecore/agent-contracts": "0.37.2",
71
- "@adecore/editor": "0.37.2",
72
- "@adecore/editor-react": "0.37.2",
73
- "@adecore/intelligent-ui": "0.37.2",
74
- "@adecore/merge": "0.37.2",
70
+ "@adecore/agent-contracts": "0.38.0",
71
+ "@adecore/editor": "0.38.0",
72
+ "@adecore/editor-react": "0.38.0",
73
+ "@adecore/intelligent-ui": "0.38.0",
74
+ "@adecore/merge": "0.38.0",
75
75
  "@codemirror/commands": "^6.11.1",
76
76
  "@codemirror/language": "^6.12.4",
77
77
  "@codemirror/state": "^6.7.6",
@@ -94,14 +94,14 @@
94
94
  "zustand": "^5.0.15"
95
95
  },
96
96
  "peerDependencies": {
97
- "@adecore/ui": "^0.37.2",
97
+ "@adecore/ui": "^0.38.0",
98
98
  "i18next": "^26.4.2",
99
99
  "react": "^19.3.0",
100
100
  "react-dom": "^19.3.0",
101
101
  "react-i18next": "^17.0.15"
102
102
  },
103
103
  "devDependencies": {
104
- "@adecore/ui": "0.37.2",
104
+ "@adecore/ui": "0.38.0",
105
105
  "@types/bun": "^1.4.2",
106
106
  "@types/react": "^19.3.0",
107
107
  "@types/react-dom": "^19.3.0",
@@ -39,6 +39,8 @@ export interface ChatSendExtras {
39
39
  /* The reply a quote at the head of the text was taken from. */
40
40
  quoteSource?: ChatQuoteSource;
41
41
  attachments?: ChatAttachmentUpload[];
42
+ /* Views and nodes picked with `#`; a machine that does not know the field drops it. */
43
+ references?: string[];
42
44
  }
43
45
 
44
46
  interface Mounted extends ChatOpenOptions, MountedEntry {
@@ -211,7 +213,8 @@ export class ChatClient {
211
213
  skills: extras.skills,
212
214
  chats: extras.chats,
213
215
  quoteSource: extras.quoteSource,
214
- attachments: extras.attachments
216
+ attachments: extras.attachments,
217
+ references: extras.references
215
218
  });
216
219
  }
217
220
 
@@ -1,11 +1,52 @@
1
+ import type { ReferenceToken } from './mentions';
2
+
1
3
  /* Another chat a message may point at, under the name it has right now. */
2
4
  export interface ProjectChat {
3
5
  id: string;
4
6
  title: string;
5
7
  }
6
8
 
7
- /* The chats an `@query` offers: never the chat typing it or one already attached. */
8
- export function chatSuggestions(chats: readonly ProjectChat[], query: string, exclude: readonly string[], limit: number): ProjectChat[] {
9
+ export type ReferableKind = 'canvas' | 'chat' | 'terminal' | 'note' | 'text' | 'drawing' | 'diagram' | 'browser' | 'device' | 'file' | 'database';
10
+
11
+ /* What a message may point at with `#`, under the name it has right now. */
12
+ export interface Referable {
13
+ id: string;
14
+ name: string;
15
+ kind: ReferableKind;
16
+ /* What tells it apart from another of the same name, such as the canvas it stands on; absent when its kind does. */
17
+ detail?: string;
18
+ /* `canvas` for what stands on the canvas the chat is a node of, `views` for a view of the project. */
19
+ group: 'canvas' | 'views';
20
+ }
21
+
22
+ export interface Referables {
23
+ /* The canvas group first, then the views; never the chat that asks. */
24
+ items: readonly Referable[];
25
+ /* The machine only resolves chats, so nothing else is offered. */
26
+ chatsOnly: boolean;
27
+ }
28
+
29
+ /* What a host without views offers: its chats, which every machine takes. */
30
+ export function referablesOfChats(chats: readonly ProjectChat[]): Referables {
31
+ return { items: chats.map((chat) => ({ id: chat.id, name: chat.title, kind: 'chat', group: 'views' })), chatsOnly: true };
32
+ }
33
+
34
+ /*
35
+ * How each id is spelled in a text: under the name it was picked with where `spelled` knows it, else
36
+ * under the name it has now. An id with neither has no token.
37
+ */
38
+ export function referenceTokens(ids: readonly string[], items: readonly Referable[], spelled: Readonly<Record<string, string>> = {}): ReferenceToken[] {
39
+ return [...new Set(ids)].flatMap((id) => {
40
+ const name = spelled[id] ?? items.find((item) => item.id === id)?.name;
41
+ return name === undefined || name === '' ? [] : [{ id, name }];
42
+ });
43
+ }
44
+
45
+ /* What a `#query` offers, the canvas first: never an id in `exclude`, and only chats where the machine takes no more. */
46
+ export function referenceSuggestions(referables: Referables, query: string, exclude: readonly string[], limit: number): Referable[] {
9
47
  const needle = query.toLowerCase();
10
- return chats.filter((chat) => !exclude.includes(chat.id) && chat.title.toLowerCase().includes(needle)).slice(0, limit);
48
+ const matches = referables.items.filter(
49
+ (item) => item.name !== '' && (!referables.chatsOnly || item.kind === 'chat') && !exclude.includes(item.id) && item.name.toLowerCase().includes(needle)
50
+ );
51
+ return [...matches.filter((item) => item.group === 'canvas'), ...matches.filter((item) => item.group === 'views')].slice(0, limit);
11
52
  }
@@ -9,16 +9,20 @@ export interface ChatDraft {
9
9
  text: string;
10
10
  mentions: string[];
11
11
  skills: string[];
12
- /* Chats of the project picked with `@`, drawn beside the text rather than in it. */
12
+ /* Chats of the project picked with `#`, by id; apart from `references`, since every machine takes a chat. */
13
13
  chats: string[];
14
14
  attachments: ChatAttachmentUpload[];
15
15
  /* A piece of an answer that goes above the text as a blockquote; empty for none. */
16
16
  quote: string;
17
17
  /* The reply the quote was taken from; null when the quote names none. */
18
18
  quoteSource: string | null;
19
+ /* Views and nodes of the project picked with `#`, by id. */
20
+ references: string[];
21
+ /* The name each pick was spelled with in the text, by id, so a chip outlives a rename; a pick without one takes the name it has now. */
22
+ referenceNames?: Record<string, string>;
19
23
  }
20
24
 
21
- export const EMPTY_DRAFT: ChatDraft = { text: '', mentions: [], skills: [], chats: [], attachments: [], quote: '', quoteSource: null };
25
+ export const EMPTY_DRAFT: ChatDraft = { text: '', mentions: [], skills: [], chats: [], attachments: [], quote: '', quoteSource: null, references: [] };
22
26
 
23
27
  // Older records only had text; the rest is filled in on read.
24
28
  type DraftRecord = {
@@ -29,6 +33,8 @@ type DraftRecord = {
29
33
  attachments?: ChatAttachmentUpload[];
30
34
  quote?: string;
31
35
  quoteSource?: string;
36
+ references?: string[];
37
+ referenceNames?: Record<string, string>;
32
38
  };
33
39
 
34
40
  const storage = persistedJson<Record<string, DraftRecord>>(
@@ -74,7 +80,9 @@ export function readDraft(chatId: string): ChatDraft {
74
80
  chats: record.chats ?? [],
75
81
  attachments: record.attachments ?? [],
76
82
  quote: record.quote ?? '',
77
- quoteSource: record.quoteSource ?? null
83
+ quoteSource: record.quoteSource ?? null,
84
+ references: record.references ?? [],
85
+ ...(record.referenceNames === undefined ? {} : { referenceNames: record.referenceNames })
78
86
  }
79
87
  : EMPTY_DRAFT;
80
88
  }
@@ -94,7 +102,9 @@ export function writeDraft(chatId: string, draft: ChatDraft): void {
94
102
  chats: draft.chats,
95
103
  attachments: draft.attachments,
96
104
  quote: draft.quote,
97
- ...(draft.quoteSource === null ? {} : { quoteSource: draft.quoteSource })
105
+ ...(draft.quoteSource === null ? {} : { quoteSource: draft.quoteSource }),
106
+ references: draft.references,
107
+ ...namesOf(draft)
98
108
  };
99
109
  if (storage.write(drafts)) {
100
110
  return;
@@ -106,11 +116,17 @@ export function writeDraft(chatId: string, draft: ChatDraft): void {
106
116
  skills: draft.skills,
107
117
  chats: draft.chats,
108
118
  quote: draft.quote,
109
- ...(draft.quoteSource === null ? {} : { quoteSource: draft.quoteSource })
119
+ ...(draft.quoteSource === null ? {} : { quoteSource: draft.quoteSource }),
120
+ references: draft.references,
121
+ ...namesOf(draft)
110
122
  };
111
123
  storage.write(drafts);
112
124
  }
113
125
 
126
+ function namesOf(draft: ChatDraft): Pick<DraftRecord, 'referenceNames'> {
127
+ return draft.referenceNames === undefined ? {} : { referenceNames: draft.referenceNames };
128
+ }
129
+
114
130
  /* Text handed to a draft from outside the composer goes under what was already typed, never over it. */
115
131
  export function joinDraftText(current: string, added: string): string {
116
132
  return current.trim() === '' ? added : `${current.replace(/\s+$/, '')}\n\n${added}`;
@@ -142,7 +158,9 @@ export function takeBackIntoDraft(
142
158
  chats: union(taken.chats, current.chats),
143
159
  attachments: [...checked.accepted.map((entry) => entry.upload), ...current.attachments],
144
160
  quote: current.quote,
145
- quoteSource: current.quoteSource
161
+ quoteSource: current.quoteSource,
162
+ references: union(taken.references, current.references),
163
+ ...namesOf(current)
146
164
  },
147
165
  rejected: checked.rejected
148
166
  };
package/src/chat/index.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  export { type AccountChoice, useAccountChoice, type NewAccountChoice, useNewAccountChoice } from './account-choice';
3
3
  export { transportActions, actionsOf, useChatActions } from './actions';
4
4
  export { type ChatSendExtras, ChatClient } from './chat-client';
5
- export type { ProjectChat } from './chat-references';
5
+ export type { ProjectChat, Referable, ReferableKind, Referables } from './chat-references';
6
6
  export { sendFromComposer, type ComposerSend } from './composer-send';
7
7
  export { stepEffortFromComposer } from './composer-effort';
8
8
  export type { EffortStep } from './logic/effort';
@@ -1,7 +1,7 @@
1
1
  import { VISUAL_LIMITS, visualFrameHeight, type ChatVisual } from '@adecore/agent-contracts/visual';
2
2
 
3
3
  /* A frame before anything measured its page: room for a chart, never taller than the page may grow. */
4
- const DEFAULT_HEIGHT_PX = 240;
4
+ export const DEFAULT_HEIGHT_PX = 240;
5
5
  /* Plenty for the visuals of a long session; the oldest goes first. */
6
6
  const REMEMBERED_HEIGHTS = 500;
7
7
  // Stay within browser layout coordinates even if a page reports a bogus finite size.