@ag-ui/proto 0.0.27
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/.turbo/turbo-build.log +23 -0
- package/.turbo/turbo-generate.log +5 -0
- package/__tests__/message-events.test.ts +268 -0
- package/__tests__/proto.test.ts +194 -0
- package/__tests__/run-events.test.ts +277 -0
- package/__tests__/state-events.test.ts +237 -0
- package/__tests__/test-utils.ts +33 -0
- package/__tests__/tool-call-events.test.ts +178 -0
- package/dist/index.d.mts +15 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +2017 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1988 -0
- package/dist/index.mjs.map +1 -0
- package/jest.config.js +5 -0
- package/package.json +35 -0
- package/src/generated/events.ts +1601 -0
- package/src/generated/google/protobuf/struct.ts +467 -0
- package/src/generated/patch.ts +129 -0
- package/src/generated/src/events.ts +1575 -0
- package/src/generated/types.ts +285 -0
- package/src/index.ts +3 -0
- package/src/proto/events.proto +143 -0
- package/src/proto/patch.proto +21 -0
- package/src/proto/types.proto +22 -0
- package/src/proto.ts +91 -0
- package/tsconfig.json +12 -0
- package/tsup.config.ts +10 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
> @ag-ui/proto@0.0.27 build /Users/mme/Code/ag-ui-protocol/typescript-sdk/packages/proto
|
|
4
|
+
> tsup
|
|
5
|
+
|
|
6
|
+
[34mCLI[39m Building entry: src/index.ts
|
|
7
|
+
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
8
|
+
[34mCLI[39m tsup v8.4.0
|
|
9
|
+
[34mCLI[39m Using tsup config: /Users/mme/Code/ag-ui-protocol/typescript-sdk/packages/proto/tsup.config.ts
|
|
10
|
+
[34mCLI[39m Target: es2019
|
|
11
|
+
[34mCLI[39m Cleaning output folder
|
|
12
|
+
[34mESM[39m Build start
|
|
13
|
+
[34mCJS[39m Build start
|
|
14
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m60.80 KB[39m
|
|
15
|
+
[32mESM[39m [1mdist/index.mjs.map [22m[32m122.38 KB[39m
|
|
16
|
+
[32mESM[39m ⚡️ Build success in 14ms
|
|
17
|
+
[32mCJS[39m [1mdist/index.js [22m[32m62.64 KB[39m
|
|
18
|
+
[32mCJS[39m [1mdist/index.js.map [22m[32m122.19 KB[39m
|
|
19
|
+
[32mCJS[39m ⚡️ Build success in 15ms
|
|
20
|
+
DTS Build start
|
|
21
|
+
DTS ⚡️ Build success in 1047ms
|
|
22
|
+
DTS dist/index.d.mts 481.00 B
|
|
23
|
+
DTS dist/index.d.ts 481.00 B
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
> @ag-ui/proto@0.0.27 generate /Users/mme/Code/ag-ui-protocol/typescript-sdk/packages/proto
|
|
4
|
+
> protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto --ts_proto_out=./src/generated --ts_proto_opt=esModuleInterop=true,outputJsonMethods=false,outputClientImpl=false -I ./src/proto ./src/proto/*.proto
|
|
5
|
+
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BaseEvent,
|
|
3
|
+
EventType,
|
|
4
|
+
MessagesSnapshotEvent,
|
|
5
|
+
TextMessageStartEvent,
|
|
6
|
+
TextMessageContentEvent,
|
|
7
|
+
TextMessageEndEvent,
|
|
8
|
+
} from "@ag-ui/core";
|
|
9
|
+
import { expect, describe, it } from "@jest/globals";
|
|
10
|
+
import { encode, decode } from "../src/proto";
|
|
11
|
+
import { expectRoundTripEquality } from "./test-utils";
|
|
12
|
+
|
|
13
|
+
describe("Message Events", () => {
|
|
14
|
+
describe("TextMessageStartEvent", () => {
|
|
15
|
+
it("should round-trip encode/decode correctly", () => {
|
|
16
|
+
const event: TextMessageStartEvent = {
|
|
17
|
+
type: EventType.TEXT_MESSAGE_START,
|
|
18
|
+
timestamp: Date.now(),
|
|
19
|
+
messageId: "msg-1",
|
|
20
|
+
role: "assistant",
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
expectRoundTripEquality(event);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("should handle missing optional fields", () => {
|
|
27
|
+
const event: TextMessageStartEvent = {
|
|
28
|
+
type: EventType.TEXT_MESSAGE_START,
|
|
29
|
+
messageId: "msg-1",
|
|
30
|
+
role: "assistant",
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
expectRoundTripEquality(event);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe("TextMessageContentEvent", () => {
|
|
38
|
+
it("should round-trip encode/decode correctly", () => {
|
|
39
|
+
const event: TextMessageContentEvent = {
|
|
40
|
+
type: EventType.TEXT_MESSAGE_CONTENT,
|
|
41
|
+
timestamp: Date.now(),
|
|
42
|
+
messageId: "msg-1",
|
|
43
|
+
delta: "Hello, how can I help you today?",
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
expectRoundTripEquality(event);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("should handle special characters in content delta", () => {
|
|
50
|
+
const event: TextMessageContentEvent = {
|
|
51
|
+
type: EventType.TEXT_MESSAGE_CONTENT,
|
|
52
|
+
messageId: "msg-1",
|
|
53
|
+
delta: "Special chars: 🚀 ñ € 😊 \n\t\"'\\`",
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
expectRoundTripEquality(event);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
describe("TextMessageEndEvent", () => {
|
|
61
|
+
it("should round-trip encode/decode correctly", () => {
|
|
62
|
+
const event: TextMessageEndEvent = {
|
|
63
|
+
type: EventType.TEXT_MESSAGE_END,
|
|
64
|
+
timestamp: Date.now(),
|
|
65
|
+
messageId: "msg-1",
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
expectRoundTripEquality(event);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
describe("MessagesSnapshotEvent", () => {
|
|
73
|
+
it("should round-trip encode/decode with multiple messages", () => {
|
|
74
|
+
const event: MessagesSnapshotEvent = {
|
|
75
|
+
type: EventType.MESSAGES_SNAPSHOT,
|
|
76
|
+
timestamp: Date.now(),
|
|
77
|
+
messages: [
|
|
78
|
+
{
|
|
79
|
+
id: "msg-1",
|
|
80
|
+
role: "user",
|
|
81
|
+
content: "Can you help me with my task?",
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
id: "msg-2",
|
|
85
|
+
role: "assistant",
|
|
86
|
+
content: "I'd be happy to help! What task do you need assistance with?",
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
expectRoundTripEquality(event);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("should handle messages with tool calls", () => {
|
|
95
|
+
const event: MessagesSnapshotEvent = {
|
|
96
|
+
type: EventType.MESSAGES_SNAPSHOT,
|
|
97
|
+
messages: [
|
|
98
|
+
{
|
|
99
|
+
id: "msg-1",
|
|
100
|
+
role: "user",
|
|
101
|
+
content: "What's the weather in San Francisco?",
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
id: "msg-2",
|
|
105
|
+
role: "assistant",
|
|
106
|
+
content: "Let me check the weather for you.",
|
|
107
|
+
toolCalls: [
|
|
108
|
+
{
|
|
109
|
+
id: "tool-1",
|
|
110
|
+
type: "function",
|
|
111
|
+
function: {
|
|
112
|
+
name: "get_weather",
|
|
113
|
+
arguments: JSON.stringify({ location: "San Francisco" }),
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
expectRoundTripEquality(event);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it("should handle messages with multiple tool calls and complex arguments", () => {
|
|
125
|
+
const event: MessagesSnapshotEvent = {
|
|
126
|
+
type: EventType.MESSAGES_SNAPSHOT,
|
|
127
|
+
messages: [
|
|
128
|
+
{
|
|
129
|
+
id: "msg-1",
|
|
130
|
+
role: "assistant",
|
|
131
|
+
content: undefined, // Changed from null to undefined
|
|
132
|
+
toolCalls: [
|
|
133
|
+
{
|
|
134
|
+
id: "tool-1",
|
|
135
|
+
type: "function",
|
|
136
|
+
function: {
|
|
137
|
+
name: "analyze_data",
|
|
138
|
+
arguments: JSON.stringify({
|
|
139
|
+
dataset: "sales_2023",
|
|
140
|
+
metrics: ["revenue", "growth", "conversion"],
|
|
141
|
+
filters: {
|
|
142
|
+
region: "North America",
|
|
143
|
+
timeframe: { start: "2023-01-01", end: "2023-12-31" },
|
|
144
|
+
},
|
|
145
|
+
}),
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
id: "tool-2",
|
|
150
|
+
type: "function",
|
|
151
|
+
function: {
|
|
152
|
+
name: "generate_report",
|
|
153
|
+
arguments: JSON.stringify({
|
|
154
|
+
title: "Annual Sales Report",
|
|
155
|
+
format: "pdf",
|
|
156
|
+
sections: ["summary", "detailed_analysis", "recommendations"],
|
|
157
|
+
}),
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
expectRoundTripEquality(event);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it("should handle messages with undefined toolCalls", () => {
|
|
169
|
+
const event: MessagesSnapshotEvent = {
|
|
170
|
+
type: EventType.MESSAGES_SNAPSHOT,
|
|
171
|
+
messages: [
|
|
172
|
+
{
|
|
173
|
+
id: "msg-1",
|
|
174
|
+
role: "user",
|
|
175
|
+
content: "Hello",
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
id: "msg-2",
|
|
179
|
+
role: "assistant",
|
|
180
|
+
content: "Hi there!",
|
|
181
|
+
// No toolCalls field
|
|
182
|
+
},
|
|
183
|
+
],
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
const encoded = encode(event);
|
|
187
|
+
const decoded = decode(encoded) as MessagesSnapshotEvent;
|
|
188
|
+
|
|
189
|
+
// Check messages length
|
|
190
|
+
expect(decoded.messages).toHaveLength(event.messages.length);
|
|
191
|
+
|
|
192
|
+
// Check first message
|
|
193
|
+
expect(decoded.messages[0].id).toBe(event.messages[0].id);
|
|
194
|
+
expect(decoded.messages[0].role).toBe(event.messages[0].role);
|
|
195
|
+
expect(decoded.messages[0].content).toBe(event.messages[0].content);
|
|
196
|
+
expect((decoded.messages[0] as any).toolCalls).toBeUndefined();
|
|
197
|
+
|
|
198
|
+
// Check second message
|
|
199
|
+
expect(decoded.messages[1].id).toBe(event.messages[1].id);
|
|
200
|
+
expect(decoded.messages[1].role).toBe(event.messages[1].role);
|
|
201
|
+
expect(decoded.messages[1].content).toBe(event.messages[1].content);
|
|
202
|
+
expect((decoded.messages[1] as any).toolCalls).toBeUndefined();
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it("should handle messages with empty toolCalls array", () => {
|
|
206
|
+
const event: MessagesSnapshotEvent = {
|
|
207
|
+
type: EventType.MESSAGES_SNAPSHOT,
|
|
208
|
+
messages: [
|
|
209
|
+
{
|
|
210
|
+
id: "msg-1",
|
|
211
|
+
role: "assistant",
|
|
212
|
+
content: "I processed your request.",
|
|
213
|
+
toolCalls: [], // Explicitly empty array
|
|
214
|
+
},
|
|
215
|
+
],
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
const encoded = encode(event);
|
|
219
|
+
const decoded = decode(encoded) as MessagesSnapshotEvent;
|
|
220
|
+
|
|
221
|
+
// Check that empty toolCalls array is converted to undefined
|
|
222
|
+
expect(decoded.messages[0].id).toBe(event.messages[0].id);
|
|
223
|
+
expect(decoded.messages[0].role).toBe(event.messages[0].role);
|
|
224
|
+
expect(decoded.messages[0].content).toBe(event.messages[0].content);
|
|
225
|
+
expect((decoded.messages[0] as any).toolCalls).toBeUndefined();
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
// Test for mixed messages (one with empty toolCalls, one with non-empty)
|
|
229
|
+
it("should correctly handle a mix of messages with empty and non-empty toolCalls", () => {
|
|
230
|
+
const event: MessagesSnapshotEvent = {
|
|
231
|
+
type: EventType.MESSAGES_SNAPSHOT,
|
|
232
|
+
messages: [
|
|
233
|
+
{
|
|
234
|
+
id: "msg-1",
|
|
235
|
+
role: "assistant",
|
|
236
|
+
content: "First message",
|
|
237
|
+
toolCalls: [], // Empty array that should be converted to undefined
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
id: "msg-2",
|
|
241
|
+
role: "assistant",
|
|
242
|
+
content: "Second message",
|
|
243
|
+
toolCalls: [
|
|
244
|
+
{
|
|
245
|
+
id: "tool-1",
|
|
246
|
+
type: "function",
|
|
247
|
+
function: {
|
|
248
|
+
name: "test_function",
|
|
249
|
+
arguments: "{}",
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
],
|
|
253
|
+
},
|
|
254
|
+
],
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
const encoded = encode(event);
|
|
258
|
+
const decoded = decode(encoded) as MessagesSnapshotEvent;
|
|
259
|
+
|
|
260
|
+
// Check first message (empty toolCalls should be undefined)
|
|
261
|
+
expect((decoded.messages[0] as any).toolCalls).toBeUndefined();
|
|
262
|
+
|
|
263
|
+
// Check second message (non-empty toolCalls should be preserved)
|
|
264
|
+
expect((decoded.messages[1] as any).toolCalls).toBeDefined();
|
|
265
|
+
expect((decoded.messages[1] as any).toolCalls?.length).toBe(1);
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
});
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { encode, decode } from "../src/proto";
|
|
2
|
+
import {
|
|
3
|
+
BaseEvent,
|
|
4
|
+
EventType,
|
|
5
|
+
StateDeltaEvent,
|
|
6
|
+
ToolCallStartEvent,
|
|
7
|
+
MessagesSnapshotEvent,
|
|
8
|
+
} from "@ag-ui/core";
|
|
9
|
+
import { describe, it, expect } from "@jest/globals";
|
|
10
|
+
import * as protoEvents from "../src/generated/events";
|
|
11
|
+
|
|
12
|
+
describe("Proto", () => {
|
|
13
|
+
it("should encode events", () => {
|
|
14
|
+
const event: BaseEvent = {
|
|
15
|
+
type: EventType.TOOL_CALL_START,
|
|
16
|
+
timestamp: Date.now(),
|
|
17
|
+
};
|
|
18
|
+
const encoded = encode(event);
|
|
19
|
+
expect(encoded).toBeInstanceOf(Uint8Array);
|
|
20
|
+
});
|
|
21
|
+
it("should handle state delta events encoding", () => {
|
|
22
|
+
const event: StateDeltaEvent = {
|
|
23
|
+
type: EventType.STATE_DELTA,
|
|
24
|
+
timestamp: Date.now(),
|
|
25
|
+
delta: [{ op: "add", path: "/foo", value: "bar" }],
|
|
26
|
+
};
|
|
27
|
+
const encoded = encode(event);
|
|
28
|
+
expect(encoded).toBeInstanceOf(Uint8Array);
|
|
29
|
+
});
|
|
30
|
+
// Test for round-trip encoding/decoding
|
|
31
|
+
it("should correctly round-trip encode/decode an event", () => {
|
|
32
|
+
const originalEvent: ToolCallStartEvent = {
|
|
33
|
+
type: EventType.TOOL_CALL_START,
|
|
34
|
+
toolCallId: "123",
|
|
35
|
+
toolCallName: "test",
|
|
36
|
+
};
|
|
37
|
+
const encoded = encode(originalEvent);
|
|
38
|
+
const decoded = decode(encoded);
|
|
39
|
+
expect(decoded.type).toBe(originalEvent.type);
|
|
40
|
+
expect(decoded.timestamp).toBe(originalEvent.timestamp);
|
|
41
|
+
});
|
|
42
|
+
// Test for StateDeltaEvent round-trip
|
|
43
|
+
it("should correctly round-trip encode/decode a StateDeltaEvent event", () => {
|
|
44
|
+
const originalEvent: StateDeltaEvent = {
|
|
45
|
+
type: EventType.STATE_DELTA,
|
|
46
|
+
timestamp: 1698765432123,
|
|
47
|
+
delta: [
|
|
48
|
+
{ op: "add", path: "/foo", value: "bar" },
|
|
49
|
+
{ op: "remove", path: "/baz" },
|
|
50
|
+
],
|
|
51
|
+
};
|
|
52
|
+
const encoded = encode(originalEvent);
|
|
53
|
+
const decoded = decode(encoded) as StateDeltaEvent;
|
|
54
|
+
|
|
55
|
+
expect(decoded.type).toBe(originalEvent.type);
|
|
56
|
+
expect(decoded.timestamp).toBe(originalEvent.timestamp);
|
|
57
|
+
expect(decoded.delta).toHaveLength(originalEvent.delta.length);
|
|
58
|
+
// Check delta operations
|
|
59
|
+
expect(decoded.delta[0].op).toBe(originalEvent.delta[0].op);
|
|
60
|
+
expect(decoded.delta[0].path).toBe(originalEvent.delta[0].path);
|
|
61
|
+
expect(decoded.delta[0].value).toBe(originalEvent.delta[0].value);
|
|
62
|
+
expect(decoded.delta[1].op).toBe(originalEvent.delta[1].op);
|
|
63
|
+
expect(decoded.delta[1].path).toBe(originalEvent.delta[1].path);
|
|
64
|
+
});
|
|
65
|
+
// Test for complex values
|
|
66
|
+
it("should correctly handle complex values in StateDeltaEvent events", () => {
|
|
67
|
+
const complexValue = {
|
|
68
|
+
nested: {
|
|
69
|
+
array: [1, 2, 3],
|
|
70
|
+
object: { key: "value" },
|
|
71
|
+
},
|
|
72
|
+
boolean: true,
|
|
73
|
+
number: 42,
|
|
74
|
+
};
|
|
75
|
+
const originalEvent: StateDeltaEvent = {
|
|
76
|
+
type: EventType.STATE_DELTA,
|
|
77
|
+
timestamp: 1698765432123,
|
|
78
|
+
delta: [{ op: "add", path: "/complex", value: complexValue }],
|
|
79
|
+
};
|
|
80
|
+
const encoded = encode(originalEvent);
|
|
81
|
+
const decoded = decode(encoded) as StateDeltaEvent;
|
|
82
|
+
expect(decoded.delta[0].value).toEqual(complexValue);
|
|
83
|
+
});
|
|
84
|
+
it("should correctly encode/decode a MessagesSnapshotEvent event with tool calls", () => {
|
|
85
|
+
const originalEvent: MessagesSnapshotEvent = {
|
|
86
|
+
type: EventType.MESSAGES_SNAPSHOT,
|
|
87
|
+
timestamp: 1698765432123,
|
|
88
|
+
messages: [
|
|
89
|
+
{
|
|
90
|
+
id: "msg-1",
|
|
91
|
+
role: "user",
|
|
92
|
+
content: "Hello, can you help me with something?",
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: "msg-2",
|
|
96
|
+
role: "assistant",
|
|
97
|
+
content: "I'll help you analyze that data.",
|
|
98
|
+
toolCalls: [
|
|
99
|
+
{
|
|
100
|
+
id: "tool-call-1",
|
|
101
|
+
type: "function",
|
|
102
|
+
function: {
|
|
103
|
+
name: "analyze_data",
|
|
104
|
+
arguments: JSON.stringify({
|
|
105
|
+
dataset: "sales_q2",
|
|
106
|
+
metrics: ["revenue", "growth"],
|
|
107
|
+
}),
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
id: "tool-call-2",
|
|
112
|
+
type: "function",
|
|
113
|
+
function: {
|
|
114
|
+
name: "generate_chart",
|
|
115
|
+
arguments: JSON.stringify({
|
|
116
|
+
chartType: "bar",
|
|
117
|
+
data: "processed_data",
|
|
118
|
+
}),
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
],
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const encoded = encode(originalEvent);
|
|
127
|
+
const decoded = decode(encoded) as MessagesSnapshotEvent;
|
|
128
|
+
|
|
129
|
+
// Verify basic event properties
|
|
130
|
+
expect(decoded.type).toBe(originalEvent.type);
|
|
131
|
+
expect(decoded.timestamp).toBe(originalEvent.timestamp);
|
|
132
|
+
|
|
133
|
+
// Verify messages array
|
|
134
|
+
expect(decoded.messages).toHaveLength(originalEvent.messages.length);
|
|
135
|
+
|
|
136
|
+
// Verify first message (user)
|
|
137
|
+
expect(decoded.messages[0].id).toBe(originalEvent.messages[0].id);
|
|
138
|
+
expect(decoded.messages[0].role).toBe(originalEvent.messages[0].role);
|
|
139
|
+
expect(decoded.messages[0].content).toBe(originalEvent.messages[0].content);
|
|
140
|
+
|
|
141
|
+
// Verify second message (assistant with tool calls)
|
|
142
|
+
expect(decoded.messages[1].id).toBe(originalEvent.messages[1].id);
|
|
143
|
+
expect(decoded.messages[1].role).toBe(originalEvent.messages[1].role);
|
|
144
|
+
expect(decoded.messages[1].content).toBe(originalEvent.messages[1].content);
|
|
145
|
+
|
|
146
|
+
// Verify tool calls
|
|
147
|
+
expect((decoded.messages[1] as any).toolCalls).toBeDefined();
|
|
148
|
+
expect((decoded.messages[1] as any).toolCalls).toHaveLength(
|
|
149
|
+
(originalEvent.messages[1] as any).toolCalls!.length,
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
// Verify first tool call
|
|
153
|
+
expect((decoded.messages[1] as any).toolCalls![0].id).toBe(
|
|
154
|
+
(originalEvent.messages[1] as any).toolCalls![0].id,
|
|
155
|
+
);
|
|
156
|
+
expect((decoded.messages[1] as any).toolCalls![0].type).toBe(
|
|
157
|
+
(originalEvent.messages[1] as any).toolCalls![0].type,
|
|
158
|
+
);
|
|
159
|
+
expect((decoded.messages[1] as any).toolCalls![0].function.name).toBe(
|
|
160
|
+
(originalEvent.messages[1] as any).toolCalls![0].function.name,
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
// Parse and compare JSON arguments
|
|
164
|
+
const decodedArgs1 = JSON.parse((decoded.messages[1] as any).toolCalls![0].function.arguments);
|
|
165
|
+
const originalArgs1 = JSON.parse(
|
|
166
|
+
(originalEvent.messages[1] as any).toolCalls![0].function.arguments,
|
|
167
|
+
);
|
|
168
|
+
expect(decodedArgs1).toEqual(originalArgs1);
|
|
169
|
+
|
|
170
|
+
// Verify second tool call
|
|
171
|
+
expect((decoded.messages[1] as any).toolCalls![1].id).toBe(
|
|
172
|
+
(originalEvent.messages[1] as any).toolCalls![1].id,
|
|
173
|
+
);
|
|
174
|
+
expect((decoded.messages[1] as any).toolCalls![1].function.name).toBe(
|
|
175
|
+
(originalEvent.messages[1] as any).toolCalls![1].function.name,
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
const decodedArgs2 = JSON.parse((decoded.messages[1] as any).toolCalls![1].function.arguments);
|
|
179
|
+
const originalArgs2 = JSON.parse(
|
|
180
|
+
(originalEvent.messages[1] as any).toolCalls![1].function.arguments,
|
|
181
|
+
);
|
|
182
|
+
expect(decodedArgs2).toEqual(originalArgs2);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
// Test for the "Invalid event" error case
|
|
186
|
+
it("should throw an error when decoding an invalid event", () => {
|
|
187
|
+
// Create an empty Event message without any oneof field set
|
|
188
|
+
const emptyEvent = protoEvents.Event.create({});
|
|
189
|
+
const encodedEmpty = protoEvents.Event.encode(emptyEvent).finish();
|
|
190
|
+
|
|
191
|
+
// Attempt to decode the empty event should throw an error
|
|
192
|
+
expect(() => decode(encodedEmpty)).toThrow("Invalid event");
|
|
193
|
+
});
|
|
194
|
+
});
|