@adecore/agents-react 0.37.1 → 0.37.3
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/dist/chat/chat-client.d.ts +1 -0
- package/dist/chat/chat-client.js +2 -1
- package/dist/chat/chat-references.d.ts +16 -1
- package/dist/chat/chat-references.js +29 -3
- package/dist/chat/drafts.d.ts +2 -0
- package/dist/chat/drafts.js +21 -5
- package/dist/chat/index.d.ts +1 -1
- package/dist/chat/logic/picker-entries.d.ts +6 -1
- package/dist/chat/logic/picker-entries.js +10 -0
- package/dist/chat/mentions.d.ts +31 -14
- package/dist/chat/mentions.js +186 -41
- package/dist/chat/stash.d.ts +1 -0
- package/dist/chat/stash.js +4 -2
- package/dist/chat/ui/Composer.js +438 -429
- package/dist/chat/ui/ComposerInput.d.ts +1 -0
- package/dist/chat/ui/ComposerInput.js +2 -0
- package/dist/chat/ui/Markdown.d.ts +3 -1
- package/dist/chat/ui/Markdown.js +194 -120
- package/dist/chat/ui/MessageActions.js +70 -66
- package/dist/chat/ui/Pickers.js +151 -207
- package/dist/chat/ui/ReferenceChip.d.ts +15 -0
- package/dist/chat/ui/ReferenceChip.js +255 -0
- package/dist/chat/ui/RunSettings.js +25 -21
- package/dist/chat/ui/Timeline.js +52 -29
- package/dist/chat/ui/TimelineMenu.js +84 -78
- package/dist/chat/ui/chip-clipboard.d.ts +9 -0
- package/dist/chat/ui/chip-clipboard.js +105 -0
- package/dist/chat/ui/chips.d.ts +5 -0
- package/dist/chat/ui/chips.js +15 -1
- package/dist/chat/ui/composer/ComposerMenu.js +140 -79
- package/dist/chat/ui/composer/DraftParts.d.ts +0 -4
- package/dist/chat/ui/composer/DraftParts.js +0 -41
- package/dist/chat/ui/composer/chip-paste.d.ts +15 -0
- package/dist/chat/ui/composer/chip-paste.js +104 -0
- package/dist/chat/ui/composer/chips.d.ts +5 -0
- package/dist/chat/ui/composer/chips.js +59 -9
- package/dist/chat/ui/composer/key-handler.js +9 -0
- package/dist/chat/ui/composer/use-composer-draft.d.ts +0 -1
- package/dist/chat/ui/composer/use-composer-draft.js +2 -10
- package/dist/chat/ui/composer/use-composer-menus.d.ts +12 -2
- package/dist/chat/ui/composer/use-composer-menus.js +192 -149
- package/dist/chat/ui/composer/use-composer-submit.js +17 -12
- package/dist/chat/ui/composer/use-draft-files.d.ts +7 -1
- package/dist/chat/ui/composer/use-draft-files.js +90 -58
- package/dist/chat/ui/composer/use-take-back.js +2 -1
- package/dist/chat/ui/index.d.ts +0 -1
- package/dist/chat/ui/index.js +0 -1
- package/dist/chat/ui/reference-icons.d.ts +3 -0
- package/dist/chat/ui/reference-icons.js +15 -0
- package/dist/chat/ui/reference-lookup.d.ts +7 -0
- package/dist/chat/ui/reference-lookup.js +6 -0
- package/dist/chat/ui/rehype-chips.d.ts +8 -1
- package/dist/chat/ui/rehype-chips.js +35 -11
- package/dist/chat/ui/rows/MessageRows.js +218 -158
- package/dist/chat/ui/thread-references.d.ts +4 -0
- package/dist/chat/ui/thread-references.js +78 -0
- package/dist/host-hooks.d.ts +2 -0
- package/dist/host-hooks.js +7 -0
- package/dist/host.d.ts +3 -0
- package/dist/locales/en/agent-chat.d.ts +20 -3
- package/dist/locales/en/agent-chat.js +24 -7
- package/dist/locales/nl/agent-chat.d.ts +20 -3
- package/dist/locales/nl/agent-chat.js +24 -7
- package/package.json +8 -8
- package/src/chat/chat-client.ts +4 -1
- package/src/chat/chat-references.ts +44 -3
- package/src/chat/drafts.ts +24 -6
- package/src/chat/index.ts +1 -1
- package/src/chat/logic/picker-entries.ts +12 -1
- package/src/chat/mentions.ts +202 -36
- package/src/chat/stash.ts +6 -2
- package/src/chat/ui/Composer.tsx +14 -4
- package/src/chat/ui/ComposerInput.tsx +4 -0
- package/src/chat/ui/Markdown.tsx +57 -25
- package/src/chat/ui/MessageActions.tsx +5 -2
- package/src/chat/ui/Pickers.tsx +8 -2
- package/src/chat/ui/ReferenceChip.tsx +74 -0
- package/src/chat/ui/RunSettings.tsx +29 -23
- package/src/chat/ui/Timeline.tsx +24 -2
- package/src/chat/ui/TimelineMenu.tsx +7 -3
- package/src/chat/ui/chip-clipboard.ts +115 -0
- package/src/chat/ui/chips.ts +20 -1
- package/src/chat/ui/composer/ComposerMenu.tsx +53 -37
- package/src/chat/ui/composer/DraftParts.tsx +0 -12
- package/src/chat/ui/composer/chip-paste.ts +122 -0
- package/src/chat/ui/composer/chips.ts +60 -10
- package/src/chat/ui/composer/key-handler.ts +9 -0
- package/src/chat/ui/composer/use-composer-draft.ts +1 -7
- package/src/chat/ui/composer/use-composer-menus.ts +68 -29
- package/src/chat/ui/composer/use-composer-submit.ts +13 -6
- package/src/chat/ui/composer/use-draft-files.ts +39 -5
- package/src/chat/ui/composer/use-take-back.ts +2 -1
- package/src/chat/ui/index.ts +0 -1
- package/src/chat/ui/reference-icons.ts +17 -0
- package/src/chat/ui/reference-lookup.ts +13 -0
- package/src/chat/ui/rehype-chips.ts +38 -13
- package/src/chat/ui/rows/MessageRows.tsx +88 -64
- package/src/chat/ui/thread-references.ts +47 -0
- package/src/host-hooks.ts +9 -0
- package/src/host.ts +6 -1
- package/src/locales/en/agent-chat.ts +24 -7
- package/src/locales/nl/agent-chat.ts +24 -7
- package/dist/chat/ui/ChatReferenceChip.d.ts +0 -4
- package/dist/chat/ui/ChatReferenceChip.js +0 -110
- package/src/chat/ui/ChatReferenceChip.tsx +0 -26
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { c as _c } from "react/compiler-runtime";
|
|
2
|
+
import { useChatHost } from '../../host.js';
|
|
3
|
+
import { useHostReferables } from '../../host-hooks.js';
|
|
4
|
+
import { useChatScope } from '../../scope.js';
|
|
5
|
+
import { useChatRow } from '../../state/chats.js';
|
|
6
|
+
const referencedOf = new WeakMap();
|
|
7
|
+
/*
|
|
8
|
+
* The ids a person pointed at with `#` in a thread, one per line. A string, so the selector that reads
|
|
9
|
+
* it answers the same value until a message with another one comes; the structure a streamed word
|
|
10
|
+
* leaves alone is what it is cached on.
|
|
11
|
+
*/
|
|
12
|
+
export function threadReferencedKey(structure) {
|
|
13
|
+
if (structure === undefined) {
|
|
14
|
+
return '';
|
|
15
|
+
}
|
|
16
|
+
const cached = referencedOf.get(structure);
|
|
17
|
+
if (cached !== undefined) {
|
|
18
|
+
return cached;
|
|
19
|
+
}
|
|
20
|
+
const ids = new Set();
|
|
21
|
+
for (const item of Object.values(structure)) {
|
|
22
|
+
if (item.kind === 'user') {
|
|
23
|
+
for (const id of [...(item.chats ?? []), ...(item.references ?? [])]) {
|
|
24
|
+
ids.add(id);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const key = [...ids].join('\n');
|
|
29
|
+
referencedOf.set(structure, key);
|
|
30
|
+
return key;
|
|
31
|
+
}
|
|
32
|
+
/* What the views, nodes and chats of a thread stand for now, and how one opens, for the rows that draw chips. */
|
|
33
|
+
export function useReferenceLookup(chatId) {
|
|
34
|
+
const $ = _c(9);
|
|
35
|
+
const {
|
|
36
|
+
id: scopeId
|
|
37
|
+
} = useChatScope();
|
|
38
|
+
const {
|
|
39
|
+
openReference
|
|
40
|
+
} = useChatHost();
|
|
41
|
+
const referables = useHostReferables(scopeId, chatId);
|
|
42
|
+
const key = useChatRow(chatId, _temp);
|
|
43
|
+
let t0;
|
|
44
|
+
if ($[0] !== openReference || $[1] !== scopeId) {
|
|
45
|
+
t0 = openReference ? id => openReference(scopeId, id) : null;
|
|
46
|
+
$[0] = openReference;
|
|
47
|
+
$[1] = scopeId;
|
|
48
|
+
$[2] = t0;
|
|
49
|
+
} else {
|
|
50
|
+
t0 = $[2];
|
|
51
|
+
}
|
|
52
|
+
let t1;
|
|
53
|
+
if ($[3] !== key) {
|
|
54
|
+
t1 = key === "" ? [] : key.split("\n");
|
|
55
|
+
$[3] = key;
|
|
56
|
+
$[4] = t1;
|
|
57
|
+
} else {
|
|
58
|
+
t1 = $[4];
|
|
59
|
+
}
|
|
60
|
+
let t2;
|
|
61
|
+
if ($[5] !== referables.items || $[6] !== t0 || $[7] !== t1) {
|
|
62
|
+
t2 = {
|
|
63
|
+
items: referables.items,
|
|
64
|
+
open: t0,
|
|
65
|
+
referenced: t1
|
|
66
|
+
};
|
|
67
|
+
$[5] = referables.items;
|
|
68
|
+
$[6] = t0;
|
|
69
|
+
$[7] = t1;
|
|
70
|
+
$[8] = t2;
|
|
71
|
+
} else {
|
|
72
|
+
t2 = $[8];
|
|
73
|
+
}
|
|
74
|
+
return t2;
|
|
75
|
+
}
|
|
76
|
+
function _temp(chat) {
|
|
77
|
+
return threadReferencedKey(chat?.structure);
|
|
78
|
+
}
|
package/dist/host-hooks.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ProviderPlatform } from '@adecore/agent-contracts';
|
|
2
|
+
import { type Referables } from './chat/chat-references.js';
|
|
2
3
|
import { type ChatHost, type CommandLook } from './host.js';
|
|
3
4
|
export declare function useHostCodeMode(): 'light' | 'dark';
|
|
4
5
|
export declare function useHostCodeThemes(): {
|
|
@@ -13,6 +14,7 @@ export declare function useHostStreaming(): ReturnType<ChatHost['useStreaming']>
|
|
|
13
14
|
export declare function useHostSendDelivery(): ReturnType<ChatHost['useSendDelivery']>;
|
|
14
15
|
export declare function useHostTimelineFind(...args: Parameters<ChatHost['useTimelineFind']>): ReturnType<ChatHost['useTimelineFind']>;
|
|
15
16
|
export declare function useHostReferableChats(): ReturnType<ChatHost['useReferableChats']>;
|
|
17
|
+
export declare function useHostReferables(scopeId: string, chatId: string): Referables;
|
|
16
18
|
export declare function useHostLoginBlocked(...args: Parameters<ChatHost['useLoginBlocked']>): ReturnType<ChatHost['useLoginBlocked']>;
|
|
17
19
|
export declare function useHostMachinePlatform(scopeId: string): ProviderPlatform | null;
|
|
18
20
|
export declare function useHostProjectLook(...args: Parameters<ChatHost['useProjectLook']>): ReturnType<ChatHost['useProjectLook']>;
|
package/dist/host-hooks.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use no memo';
|
|
2
2
|
|
|
3
|
+
import { referablesOfChats } from './chat/chat-references.js';
|
|
3
4
|
import { useChatHost } from './host.js';
|
|
4
5
|
export function useHostCodeMode() {
|
|
5
6
|
return useChatHost().code.useMode();
|
|
@@ -31,6 +32,12 @@ export function useHostTimelineFind(...args) {
|
|
|
31
32
|
export function useHostReferableChats() {
|
|
32
33
|
return useChatHost().useReferableChats();
|
|
33
34
|
}
|
|
35
|
+
const useReferablesFromChats = (_scopeId, _chatId) => referablesOfChats(useHostReferableChats());
|
|
36
|
+
/* A host without views of its own offers its chats. */
|
|
37
|
+
export function useHostReferables(scopeId, chatId) {
|
|
38
|
+
const useReferables = useChatHost().useReferables ?? useReferablesFromChats;
|
|
39
|
+
return useReferables(scopeId, chatId);
|
|
40
|
+
}
|
|
34
41
|
export function useHostLoginBlocked(...args) {
|
|
35
42
|
return useChatHost().useLoginBlocked(...args);
|
|
36
43
|
}
|
package/dist/host.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { EditorView } from '@codemirror/view';
|
|
|
4
4
|
import type { Highlighter, ThemeRegistration } from 'shiki';
|
|
5
5
|
import type { EditorEngine } from '@adecore/editor';
|
|
6
6
|
import type { AgentKind, ChatCheckpointDiff, ChatConfigurePayload, ChatGoalAction, ChatItem, ChatSubagentItem, ChatUiChoicePayload, ChatUiQueryPayload, ChatUiQueryReading, ChatUiLinkPayload, ChatUiLinkReading, ProviderPlatform } from '@adecore/agent-contracts';
|
|
7
|
+
import type { Referables } from './chat/chat-references.js';
|
|
7
8
|
import type { TimelineRow } from './chat/logic/timeline.js';
|
|
8
9
|
import type { FindReveal } from './chat/ui/find-reveal.js';
|
|
9
10
|
import type { PromptAction } from './prompts/logic/prompts.js';
|
|
@@ -247,6 +248,8 @@ export interface ChatHost {
|
|
|
247
248
|
id: string;
|
|
248
249
|
title: string;
|
|
249
250
|
}>;
|
|
251
|
+
useReferables?(scopeId: string, chatId: string): Referables;
|
|
252
|
+
openReference?(scopeId: string, id: string): void;
|
|
250
253
|
openLogin: ((scopeId: string, kind: AgentKind, accountId: string, name: string) => Promise<void>) | null;
|
|
251
254
|
useLoginBlocked(scopeId: string): string | null;
|
|
252
255
|
runProviderCommand?(scopeId: string, kind: AgentKind, command: string): void;
|
|
@@ -16,10 +16,9 @@ declare const _default: {
|
|
|
16
16
|
unreadable: string;
|
|
17
17
|
unreadableThumbnail: string;
|
|
18
18
|
};
|
|
19
|
-
|
|
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: 'Could not read {{name}}',
|
|
17
17
|
unreadableThumbnail: 'Could not read the thumbnail'
|
|
18
18
|
},
|
|
19
|
-
|
|
20
|
-
gone: '
|
|
21
|
-
untitled: 'Untitled
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
20
|
-
gone: '
|
|
21
|
-
untitled: '
|
|
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
|
-
|
|
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.
|
|
3
|
+
"version": "0.37.3",
|
|
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.
|
|
71
|
-
"@adecore/editor": "0.37.
|
|
72
|
-
"@adecore/editor-react": "0.37.
|
|
73
|
-
"@adecore/intelligent-ui": "0.37.
|
|
74
|
-
"@adecore/merge": "0.37.
|
|
70
|
+
"@adecore/agent-contracts": "0.37.3",
|
|
71
|
+
"@adecore/editor": "0.37.3",
|
|
72
|
+
"@adecore/editor-react": "0.37.3",
|
|
73
|
+
"@adecore/intelligent-ui": "0.37.3",
|
|
74
|
+
"@adecore/merge": "0.37.3",
|
|
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.
|
|
97
|
+
"@adecore/ui": "^0.37.3",
|
|
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.
|
|
104
|
+
"@adecore/ui": "0.37.3",
|
|
105
105
|
"@types/bun": "^1.4.2",
|
|
106
106
|
"@types/react": "^19.3.0",
|
|
107
107
|
"@types/react-dom": "^19.3.0",
|
package/src/chat/chat-client.ts
CHANGED
|
@@ -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
|
-
|
|
8
|
-
|
|
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
|
-
|
|
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
|
}
|
package/src/chat/drafts.ts
CHANGED
|
@@ -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
|
|
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,6 +1,17 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { pickerGroupsOf, providerGroupOf, type AgentKind, type ModelInfo, type ProviderInfo } from '@adecore/agent-contracts';
|
|
2
2
|
import { nameCollator } from '@adecore/ui/format';
|
|
3
3
|
|
|
4
|
+
/* The providers in the order a picker lists them: the frontier labs, the rest, then the API providers, each by name. */
|
|
5
|
+
export function inPickerOrder<T extends { kind: AgentKind; name: string }>(providers: readonly T[]): T[] {
|
|
6
|
+
const groups = pickerGroupsOf(providers);
|
|
7
|
+
return [...groups.frontier, ...groups.others, ...groups.api];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/* Whether a separator goes between two providers next to each other in that order: where one group ends. */
|
|
11
|
+
export function separatesGroups(previous: AgentKind | undefined, kind: AgentKind): boolean {
|
|
12
|
+
return previous !== undefined && providerGroupOf(previous) !== providerGroupOf(kind);
|
|
13
|
+
}
|
|
14
|
+
|
|
4
15
|
/*
|
|
5
16
|
* A provider with more live models than this keeps the list short: the model that is picked and the default,
|
|
6
17
|
* with the rest behind one row that opens all of them. A list of three hundred models is not one to scroll.
|