@adecore/agent-contracts 0.49.6 → 0.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chat.js +27 -14
- package/dist/envelope.js +9 -0
- package/dist/text.js +4 -0
- package/package.json +2 -2
- package/src/chat.ts +34 -15
- package/src/envelope.ts +12 -0
- package/src/text.ts +5 -0
package/dist/chat.js
CHANGED
|
@@ -644,14 +644,24 @@ export const ChatItemSchema = z.discriminatedUnion('kind', [
|
|
|
644
644
|
export function activeSubagents(items) {
|
|
645
645
|
const lastMessage = items.findLastIndex((item) => item.kind === 'user');
|
|
646
646
|
const lastMessageAt = lastMessage < 0 ? null : items[lastMessage].createdAt;
|
|
647
|
-
const
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
647
|
+
const turns = new Set();
|
|
648
|
+
for (const item of items) {
|
|
649
|
+
if (item.kind === 'subagent' && item.status === 'running' && item.turnId !== null) {
|
|
650
|
+
turns.add(item.turnId);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
const active = [];
|
|
654
|
+
for (let index = 0; index < items.length; index++) {
|
|
655
|
+
const item = items[index];
|
|
656
|
+
if (item.kind === 'subagent' &&
|
|
657
|
+
(item.status === 'running' ||
|
|
658
|
+
index > lastMessage ||
|
|
659
|
+
(lastMessageAt !== null && item.finishedAt !== null && item.finishedAt > lastMessageAt) ||
|
|
660
|
+
(item.turnId !== null && turns.has(item.turnId)))) {
|
|
661
|
+
active.push(item);
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
return active;
|
|
655
665
|
}
|
|
656
666
|
/*
|
|
657
667
|
* When a workflow last did something it could be shown for: the end the host noted, else the last end
|
|
@@ -691,21 +701,24 @@ export const CHAT_OUTLINE_TEXT_CHARS = 280;
|
|
|
691
701
|
* A message of only attachments keeps their names. `items` is in thread order.
|
|
692
702
|
*/
|
|
693
703
|
export function outlineItems(items, marked = new Set()) {
|
|
694
|
-
|
|
704
|
+
const outline = [];
|
|
705
|
+
for (const item of items) {
|
|
695
706
|
const { id, createdAt, turnId } = item;
|
|
696
707
|
if (item.kind === 'user') {
|
|
697
708
|
const text = item.text.slice(0, CHAT_OUTLINE_TEXT_CHARS);
|
|
698
|
-
|
|
709
|
+
outline.push({ id, createdAt, turnId, kind: 'user', text, ...(text === '' && item.attachments ? { attachments: item.attachments } : {}) });
|
|
710
|
+
continue;
|
|
699
711
|
}
|
|
700
712
|
if (item.kind === 'turn' && ((item.taskIds?.length ?? 0) > 0 || (item.messageFrom?.length ?? 0) > 0)) {
|
|
701
713
|
const { checkpointDiff: _checkpointDiff, ...turn } = item;
|
|
702
|
-
|
|
714
|
+
outline.push(turn);
|
|
715
|
+
continue;
|
|
703
716
|
}
|
|
704
717
|
if (item.kind === 'assistant' && marked.has(id)) {
|
|
705
|
-
|
|
718
|
+
outline.push({ id, createdAt, turnId, kind: 'assistant', text: item.text.slice(0, CHAT_OUTLINE_TEXT_CHARS), streaming: false });
|
|
706
719
|
}
|
|
707
|
-
|
|
708
|
-
|
|
720
|
+
}
|
|
721
|
+
return outline;
|
|
709
722
|
}
|
|
710
723
|
// Events apply after the `chat.attach` snapshot; item ids make upserts and streamed deltas replayable.
|
|
711
724
|
export const ChatEventSchema = z.discriminatedUnion('type', [
|
package/dist/envelope.js
CHANGED
|
@@ -36,5 +36,14 @@ export function parseRequest(input) {
|
|
|
36
36
|
return toResult(RequestSchema.safeParse(input));
|
|
37
37
|
}
|
|
38
38
|
export function parseServerFrame(input) {
|
|
39
|
+
if (typeof input === 'object' && input !== null) {
|
|
40
|
+
const frame = input;
|
|
41
|
+
if (!('ok' in input) && frame.type === 'event' && typeof frame.event === 'string' && frame.event !== '') {
|
|
42
|
+
const event = EventSchema.safeParse(input);
|
|
43
|
+
if (event.success) {
|
|
44
|
+
return toResult(event);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
39
48
|
return toResult(ServerFrameSchema.safeParse(input));
|
|
40
49
|
}
|
package/dist/text.js
CHANGED
|
@@ -8,6 +8,10 @@ export function clipText(text, max) {
|
|
|
8
8
|
if (text.length <= max) {
|
|
9
9
|
return text;
|
|
10
10
|
}
|
|
11
|
+
if (Number.isInteger(max) && max >= 0 && /^\p{ASCII}*$/u.test(text.slice(0, max + 1))) {
|
|
12
|
+
// CRLF is the only multi-unit ASCII grapheme; inspect the next unit before cutting.
|
|
13
|
+
return text.slice(0, text[max - 1] === '\r' && text[max] === '\n' ? max - 1 : max);
|
|
14
|
+
}
|
|
11
15
|
graphemes ??= new Intl.Segmenter(undefined, { granularity: 'grapheme' });
|
|
12
16
|
let end = 0;
|
|
13
17
|
for (const { segment } of graphemes.segment(text)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adecore/agent-contracts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.50.0",
|
|
4
4
|
"description": "Schemas and port contracts for agent chats, provider accounts, models and usage.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"test": "bun --conditions=source test"
|
|
87
87
|
},
|
|
88
88
|
"dependencies": {
|
|
89
|
-
"@adecore/intelligent-ui": "0.
|
|
89
|
+
"@adecore/intelligent-ui": "0.50.0",
|
|
90
90
|
"zod": "^4.6.7"
|
|
91
91
|
},
|
|
92
92
|
"devDependencies": {
|
package/src/chat.ts
CHANGED
|
@@ -779,18 +779,31 @@ export type ChatCompactionItem = z.infer<typeof ChatCompactionItemSchema>;
|
|
|
779
779
|
export function activeSubagents(items: readonly ChatItem[]): ChatSubagentItem[] {
|
|
780
780
|
const lastMessage = items.findLastIndex((item) => item.kind === 'user');
|
|
781
781
|
const lastMessageAt = lastMessage < 0 ? null : items[lastMessage]!.createdAt;
|
|
782
|
-
const
|
|
783
|
-
const turns = new Set(rows.flatMap(({ item }) => (item.status === 'running' && item.turnId !== null ? [item.turnId] : [])));
|
|
782
|
+
const turns = new Set<string>();
|
|
784
783
|
|
|
785
|
-
|
|
786
|
-
.
|
|
787
|
-
(
|
|
788
|
-
|
|
784
|
+
for (const item of items) {
|
|
785
|
+
if (item.kind === 'subagent' && item.status === 'running' && item.turnId !== null) {
|
|
786
|
+
turns.add(item.turnId);
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
const active: ChatSubagentItem[] = [];
|
|
791
|
+
|
|
792
|
+
for (let index = 0; index < items.length; index++) {
|
|
793
|
+
const item = items[index]!;
|
|
794
|
+
|
|
795
|
+
if (
|
|
796
|
+
item.kind === 'subagent' &&
|
|
797
|
+
(item.status === 'running' ||
|
|
789
798
|
index > lastMessage ||
|
|
790
799
|
(lastMessageAt !== null && item.finishedAt !== null && item.finishedAt > lastMessageAt) ||
|
|
791
|
-
(item.turnId !== null && turns.has(item.turnId))
|
|
792
|
-
)
|
|
793
|
-
|
|
800
|
+
(item.turnId !== null && turns.has(item.turnId)))
|
|
801
|
+
) {
|
|
802
|
+
active.push(item);
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
return active;
|
|
794
807
|
}
|
|
795
808
|
|
|
796
809
|
/*
|
|
@@ -840,27 +853,33 @@ export const CHAT_OUTLINE_TEXT_CHARS = 280;
|
|
|
840
853
|
* A message of only attachments keeps their names. `items` is in thread order.
|
|
841
854
|
*/
|
|
842
855
|
export function outlineItems(items: readonly ChatItem[], marked: ReadonlySet<string> = new Set()): ChatItem[] {
|
|
843
|
-
|
|
856
|
+
const outline: ChatItem[] = [];
|
|
857
|
+
|
|
858
|
+
for (const item of items) {
|
|
844
859
|
const { id, createdAt, turnId } = item;
|
|
845
860
|
|
|
846
861
|
if (item.kind === 'user') {
|
|
847
862
|
const text = item.text.slice(0, CHAT_OUTLINE_TEXT_CHARS);
|
|
848
863
|
|
|
849
|
-
|
|
864
|
+
outline.push({ id, createdAt, turnId, kind: 'user', text, ...(text === '' && item.attachments ? { attachments: item.attachments } : {}) });
|
|
865
|
+
|
|
866
|
+
continue;
|
|
850
867
|
}
|
|
851
868
|
|
|
852
869
|
if (item.kind === 'turn' && ((item.taskIds?.length ?? 0) > 0 || (item.messageFrom?.length ?? 0) > 0)) {
|
|
853
870
|
const { checkpointDiff: _checkpointDiff, ...turn } = item;
|
|
854
871
|
|
|
855
|
-
|
|
872
|
+
outline.push(turn);
|
|
873
|
+
|
|
874
|
+
continue;
|
|
856
875
|
}
|
|
857
876
|
|
|
858
877
|
if (item.kind === 'assistant' && marked.has(id)) {
|
|
859
|
-
|
|
878
|
+
outline.push({ id, createdAt, turnId, kind: 'assistant', text: item.text.slice(0, CHAT_OUTLINE_TEXT_CHARS), streaming: false });
|
|
860
879
|
}
|
|
880
|
+
}
|
|
861
881
|
|
|
862
|
-
|
|
863
|
-
});
|
|
882
|
+
return outline;
|
|
864
883
|
}
|
|
865
884
|
|
|
866
885
|
// Events apply after the `chat.attach` snapshot; item ids make upserts and streamed deltas replayable.
|
package/src/envelope.ts
CHANGED
|
@@ -56,5 +56,17 @@ export function parseRequest(input: unknown): ParseResult<Request> {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
export function parseServerFrame(input: unknown): ParseResult<ServerFrame> {
|
|
59
|
+
if (typeof input === 'object' && input !== null) {
|
|
60
|
+
const frame = input as { type?: unknown; event?: unknown };
|
|
61
|
+
|
|
62
|
+
if (!('ok' in input) && frame.type === 'event' && typeof frame.event === 'string' && frame.event !== '') {
|
|
63
|
+
const event = EventSchema.safeParse(input);
|
|
64
|
+
|
|
65
|
+
if (event.success) {
|
|
66
|
+
return toResult(event);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
59
71
|
return toResult(ServerFrameSchema.safeParse(input));
|
|
60
72
|
}
|
package/src/text.ts
CHANGED
|
@@ -10,6 +10,11 @@ export function clipText(text: string, max: number): string {
|
|
|
10
10
|
return text;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
if (Number.isInteger(max) && max >= 0 && /^\p{ASCII}*$/u.test(text.slice(0, max + 1))) {
|
|
14
|
+
// CRLF is the only multi-unit ASCII grapheme; inspect the next unit before cutting.
|
|
15
|
+
return text.slice(0, text[max - 1] === '\r' && text[max] === '\n' ? max - 1 : max);
|
|
16
|
+
}
|
|
17
|
+
|
|
13
18
|
graphemes ??= new Intl.Segmenter(undefined, { granularity: 'grapheme' });
|
|
14
19
|
let end = 0;
|
|
15
20
|
|