@copilotkitnext/runtime 0.0.3 → 0.0.5

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 (40) hide show
  1. package/dist/index.js +1 -1
  2. package/dist/index.js.map +1 -1
  3. package/dist/index.mjs +1 -1
  4. package/dist/index.mjs.map +1 -1
  5. package/package.json +2 -2
  6. package/.turbo/turbo-build.log +0 -23
  7. package/.turbo/turbo-check-types.log +0 -4
  8. package/.turbo/turbo-lint.log +0 -56
  9. package/.turbo/turbo-test$colon$coverage.log +0 -149
  10. package/.turbo/turbo-test.log +0 -108
  11. package/src/__tests__/get-runtime-info.test.ts +0 -117
  12. package/src/__tests__/handle-run.test.ts +0 -69
  13. package/src/__tests__/handle-transcribe.test.ts +0 -289
  14. package/src/__tests__/in-process-agent-runner-messages.test.ts +0 -599
  15. package/src/__tests__/in-process-agent-runner.test.ts +0 -726
  16. package/src/__tests__/middleware.test.ts +0 -432
  17. package/src/__tests__/routing.test.ts +0 -257
  18. package/src/endpoint.ts +0 -150
  19. package/src/handler.ts +0 -3
  20. package/src/handlers/get-runtime-info.ts +0 -50
  21. package/src/handlers/handle-connect.ts +0 -144
  22. package/src/handlers/handle-run.ts +0 -156
  23. package/src/handlers/handle-transcribe.ts +0 -126
  24. package/src/index.ts +0 -8
  25. package/src/middleware.ts +0 -232
  26. package/src/runner/__tests__/enterprise-runner.test.ts +0 -992
  27. package/src/runner/__tests__/event-compaction.test.ts +0 -253
  28. package/src/runner/__tests__/in-memory-runner.test.ts +0 -483
  29. package/src/runner/__tests__/sqlite-runner.test.ts +0 -975
  30. package/src/runner/agent-runner.ts +0 -27
  31. package/src/runner/enterprise.ts +0 -653
  32. package/src/runner/event-compaction.ts +0 -250
  33. package/src/runner/in-memory.ts +0 -328
  34. package/src/runner/index.ts +0 -0
  35. package/src/runner/sqlite.ts +0 -481
  36. package/src/runtime.ts +0 -53
  37. package/src/transcription-service/transcription-service-openai.ts +0 -29
  38. package/src/transcription-service/transcription-service.ts +0 -11
  39. package/tsconfig.json +0 -13
  40. package/tsup.config.ts +0 -11
@@ -1,483 +0,0 @@
1
- import { describe, it, expect, beforeEach } from "vitest";
2
- import { InMemoryAgentRunner } from "../in-memory";
3
- import {
4
- AbstractAgent,
5
- BaseEvent,
6
- EventType,
7
- Message,
8
- RunAgentInput,
9
- TextMessageContentEvent,
10
- TextMessageEndEvent,
11
- TextMessageStartEvent,
12
- ToolCallResultEvent,
13
- } from "@ag-ui/client";
14
- import { firstValueFrom } from "rxjs";
15
- import { toArray } from "rxjs/operators";
16
-
17
- class TestAgent extends AbstractAgent {
18
- private events: BaseEvent[] = [];
19
-
20
- constructor(events: BaseEvent[] = []) {
21
- super();
22
- this.events = events;
23
- }
24
-
25
- async runAgent(
26
- input: RunAgentInput,
27
- options: {
28
- onEvent: (event: { event: BaseEvent }) => void;
29
- onNewMessage?: (args: { message: Message }) => void;
30
- onRunStartedEvent?: () => void;
31
- }
32
- ): Promise<void> {
33
- // Call onRunStartedEvent to trigger message injection
34
- if (options.onRunStartedEvent) {
35
- options.onRunStartedEvent();
36
- }
37
-
38
- // Emit test events
39
- for (const event of this.events) {
40
- options.onEvent({ event });
41
- }
42
-
43
- // Call onNewMessage for assistant messages we generate
44
- if (options.onNewMessage) {
45
- const assistantMessage: Message = {
46
- id: "assistant-msg-1",
47
- role: "assistant",
48
- content: "Test response",
49
- };
50
- options.onNewMessage({ message: assistantMessage });
51
- }
52
- }
53
-
54
- clone(): AbstractAgent {
55
- return new TestAgent(this.events);
56
- }
57
- }
58
-
59
- describe("InMemoryAgentRunner", () => {
60
- let runner: InMemoryAgentRunner;
61
-
62
- beforeEach(() => {
63
- runner = new InMemoryAgentRunner();
64
- });
65
-
66
- describe("Event Storage", () => {
67
- it("should not store empty events", async () => {
68
- const threadId = "test-thread-no-empty";
69
- const agent = new TestAgent([]);
70
-
71
- const input: RunAgentInput = {
72
- messages: [],
73
- state: {},
74
- threadId,
75
- runId: "run-1",
76
- };
77
-
78
- await firstValueFrom(
79
- runner.run({ threadId, agent, input }).pipe(toArray())
80
- );
81
-
82
- // Connect and get stored events
83
- const storedEvents = await firstValueFrom(
84
- runner.connect({ threadId }).pipe(toArray())
85
- );
86
-
87
- // No events should be stored
88
- expect(storedEvents).toHaveLength(0);
89
- });
90
-
91
- it("should store and compact text message events", async () => {
92
- const threadId = "test-thread-compact";
93
-
94
- const events: BaseEvent[] = [
95
- {
96
- type: EventType.TEXT_MESSAGE_START,
97
- messageId: "msg-1",
98
- role: "assistant",
99
- } as TextMessageStartEvent,
100
- {
101
- type: EventType.TEXT_MESSAGE_CONTENT,
102
- messageId: "msg-1",
103
- delta: "Hello",
104
- } as TextMessageContentEvent,
105
- {
106
- type: EventType.TEXT_MESSAGE_CONTENT,
107
- messageId: "msg-1",
108
- delta: " world",
109
- } as TextMessageContentEvent,
110
- {
111
- type: EventType.TEXT_MESSAGE_END,
112
- messageId: "msg-1",
113
- } as TextMessageEndEvent,
114
- ];
115
-
116
- const agent = new TestAgent(events);
117
- const input: RunAgentInput = {
118
- messages: [],
119
- state: {},
120
- threadId,
121
- runId: "run-1",
122
- };
123
-
124
- await firstValueFrom(
125
- runner.run({ threadId, agent, input }).pipe(toArray())
126
- );
127
-
128
- // Connect and get stored events
129
- const storedEvents = await firstValueFrom(
130
- runner.connect({ threadId }).pipe(toArray())
131
- );
132
-
133
- // Should have start, single content (compacted), and end events
134
- expect(storedEvents).toHaveLength(3);
135
- expect(storedEvents[0].type).toBe(EventType.TEXT_MESSAGE_START);
136
- expect(storedEvents[1].type).toBe(EventType.TEXT_MESSAGE_CONTENT);
137
- expect((storedEvents[1] as TextMessageContentEvent).delta).toBe("Hello world");
138
- expect(storedEvents[2].type).toBe(EventType.TEXT_MESSAGE_END);
139
- });
140
-
141
- it("should not store duplicate message IDs across multiple runs", async () => {
142
- const threadId = "test-thread-no-duplicates";
143
- const userMessage: Message = {
144
- id: "user-msg-1",
145
- role: "user",
146
- content: "Hello",
147
- };
148
-
149
- // First run
150
- const agent1 = new TestAgent([
151
- {
152
- type: EventType.TEXT_MESSAGE_START,
153
- messageId: "assistant-msg-1",
154
- role: "assistant",
155
- } as TextMessageStartEvent,
156
- {
157
- type: EventType.TEXT_MESSAGE_CONTENT,
158
- messageId: "assistant-msg-1",
159
- delta: "Hi from run 1",
160
- } as TextMessageContentEvent,
161
- {
162
- type: EventType.TEXT_MESSAGE_END,
163
- messageId: "assistant-msg-1",
164
- } as TextMessageEndEvent,
165
- ]);
166
-
167
- const input1: RunAgentInput = {
168
- messages: [userMessage],
169
- state: {},
170
- threadId,
171
- runId: "run-1",
172
- };
173
-
174
- await firstValueFrom(
175
- runner.run({ threadId, agent: agent1, input: input1 }).pipe(toArray())
176
- );
177
-
178
- // Second run with same user message plus new one
179
- const newUserMessage: Message = {
180
- id: "user-msg-2",
181
- role: "user",
182
- content: "How are you?",
183
- };
184
-
185
- const agent2 = new TestAgent([
186
- {
187
- type: EventType.TEXT_MESSAGE_START,
188
- messageId: "assistant-msg-2",
189
- role: "assistant",
190
- } as TextMessageStartEvent,
191
- {
192
- type: EventType.TEXT_MESSAGE_CONTENT,
193
- messageId: "assistant-msg-2",
194
- delta: "Hi from run 2",
195
- } as TextMessageContentEvent,
196
- {
197
- type: EventType.TEXT_MESSAGE_END,
198
- messageId: "assistant-msg-2",
199
- } as TextMessageEndEvent,
200
- ]);
201
-
202
- const input2: RunAgentInput = {
203
- messages: [userMessage, newUserMessage],
204
- state: {},
205
- threadId,
206
- runId: "run-2",
207
- };
208
-
209
- await firstValueFrom(
210
- runner.run({ threadId, agent: agent2, input: input2 }).pipe(toArray())
211
- );
212
-
213
- // Connect and get all stored events
214
- const storedEvents = await firstValueFrom(
215
- runner.connect({ threadId }).pipe(toArray())
216
- );
217
-
218
- // Count unique message IDs
219
- const messageIds = new Set<string>();
220
- for (const event of storedEvents) {
221
- if ('messageId' in event && event.messageId) {
222
- messageIds.add(event.messageId);
223
- }
224
- }
225
-
226
- // Should have: user-msg-1, assistant-msg-1, user-msg-2, assistant-msg-2
227
- expect(messageIds.size).toBe(4);
228
- expect(messageIds.has("user-msg-1")).toBe(true);
229
- expect(messageIds.has("assistant-msg-1")).toBe(true);
230
- expect(messageIds.has("user-msg-2")).toBe(true);
231
- expect(messageIds.has("assistant-msg-2")).toBe(true);
232
-
233
- // Check that each message ID appears only once in start events
234
- const startEvents = storedEvents.filter(e => e.type === EventType.TEXT_MESSAGE_START);
235
- const startMessageIds = startEvents.map(e => (e as any).messageId);
236
- const uniqueStartIds = new Set(startMessageIds);
237
- expect(startMessageIds.length).toBe(uniqueStartIds.size);
238
- });
239
-
240
- it("should store all types of new messages (user, assistant, tool, system, developer)", async () => {
241
- const threadId = "test-thread-all-messages";
242
-
243
- const messages: Message[] = [
244
- { id: "user-1", role: "user", content: "User message" },
245
- { id: "system-1", role: "system", content: "System message" },
246
- { id: "developer-1", role: "developer", content: "Developer message" },
247
- { id: "tool-1", role: "tool", content: "Tool result", toolCallId: "tool-call-1" },
248
- ];
249
-
250
- const agent = new TestAgent([
251
- {
252
- type: EventType.TEXT_MESSAGE_START,
253
- messageId: "assistant-1",
254
- role: "assistant",
255
- } as TextMessageStartEvent,
256
- {
257
- type: EventType.TEXT_MESSAGE_CONTENT,
258
- messageId: "assistant-1",
259
- delta: "Assistant response",
260
- } as TextMessageContentEvent,
261
- {
262
- type: EventType.TEXT_MESSAGE_END,
263
- messageId: "assistant-1",
264
- } as TextMessageEndEvent,
265
- ]);
266
-
267
- const input: RunAgentInput = {
268
- messages,
269
- state: {},
270
- threadId,
271
- runId: "run-1",
272
- };
273
-
274
- await firstValueFrom(
275
- runner.run({ threadId, agent, input }).pipe(toArray())
276
- );
277
-
278
- // Connect and get stored events
279
- const storedEvents = await firstValueFrom(
280
- runner.connect({ threadId }).pipe(toArray())
281
- );
282
-
283
- // Collect all message IDs
284
- const messageIds = new Set<string>();
285
- for (const event of storedEvents) {
286
- if ('messageId' in event && event.messageId) {
287
- messageIds.add(event.messageId);
288
- }
289
- }
290
-
291
- // Should have all message types
292
- expect(messageIds.has("user-1")).toBe(true);
293
- expect(messageIds.has("system-1")).toBe(true);
294
- expect(messageIds.has("developer-1")).toBe(true);
295
- expect(messageIds.has("tool-1")).toBe(true);
296
- expect(messageIds.has("assistant-1")).toBe(true);
297
-
298
- // Check tool result event
299
- const toolEvents = storedEvents.filter(e => e.type === EventType.TOOL_CALL_RESULT);
300
- expect(toolEvents).toHaveLength(1);
301
- const toolEvent = toolEvents[0] as ToolCallResultEvent;
302
- expect(toolEvent.messageId).toBe("tool-1");
303
- expect(toolEvent.content).toBe("Tool result");
304
- expect(toolEvent.toolCallId).toBe("tool-call-1");
305
- });
306
-
307
- it("should only store new messages for each run", async () => {
308
- const threadId = "test-thread-only-new";
309
-
310
- // First run
311
- const message1: Message = { id: "msg-1", role: "user", content: "First" };
312
- const agent1 = new TestAgent([]);
313
- const input1: RunAgentInput = {
314
- messages: [message1],
315
- state: {},
316
- threadId,
317
- runId: "run-1",
318
- };
319
-
320
- await firstValueFrom(
321
- runner.run({ threadId, agent: agent1, input: input1 }).pipe(toArray())
322
- );
323
-
324
- // Second run with old message and new message
325
- const message2: Message = { id: "msg-2", role: "user", content: "Second" };
326
- const agent2 = new TestAgent([]);
327
- const input2: RunAgentInput = {
328
- messages: [message1, message2], // Include old message for context
329
- state: {},
330
- threadId,
331
- runId: "run-2",
332
- };
333
-
334
- await firstValueFrom(
335
- runner.run({ threadId, agent: agent2, input: input2 }).pipe(toArray())
336
- );
337
-
338
- // Third run with all old messages and one new
339
- const message3: Message = { id: "msg-3", role: "user", content: "Third" };
340
- const agent3 = new TestAgent([]);
341
- const input3: RunAgentInput = {
342
- messages: [message1, message2, message3],
343
- state: {},
344
- threadId,
345
- runId: "run-3",
346
- };
347
-
348
- await firstValueFrom(
349
- runner.run({ threadId, agent: agent3, input: input3 }).pipe(toArray())
350
- );
351
-
352
- // Connect and verify each message appears only once
353
- const storedEvents = await firstValueFrom(
354
- runner.connect({ threadId }).pipe(toArray())
355
- );
356
-
357
- // Count start events for each message
358
- const startEvents = storedEvents.filter(e => e.type === EventType.TEXT_MESSAGE_START);
359
- const messageIdCounts = new Map<string, number>();
360
-
361
- for (const event of startEvents) {
362
- const messageId = (event as any).messageId;
363
- messageIdCounts.set(messageId, (messageIdCounts.get(messageId) || 0) + 1);
364
- }
365
-
366
- // Each message should appear exactly once
367
- expect(messageIdCounts.get("msg-1")).toBe(1);
368
- expect(messageIdCounts.get("msg-2")).toBe(1);
369
- expect(messageIdCounts.get("msg-3")).toBe(1);
370
- });
371
-
372
- it("should handle tool messages correctly", async () => {
373
- const threadId = "test-thread-tool-messages";
374
-
375
- const toolMessage: Message = {
376
- id: "tool-msg-1",
377
- role: "tool",
378
- content: "Tool execution result",
379
- toolCallId: "tool-call-123",
380
- };
381
-
382
- const agent = new TestAgent([]);
383
- const input: RunAgentInput = {
384
- messages: [toolMessage],
385
- state: {},
386
- threadId,
387
- runId: "run-1",
388
- };
389
-
390
- await firstValueFrom(
391
- runner.run({ threadId, agent, input }).pipe(toArray())
392
- );
393
-
394
- // Connect and get stored events
395
- const storedEvents = await firstValueFrom(
396
- runner.connect({ threadId }).pipe(toArray())
397
- );
398
-
399
- // Should have the tool result event
400
- const toolEvents = storedEvents.filter(e => e.type === EventType.TOOL_CALL_RESULT);
401
- expect(toolEvents).toHaveLength(1);
402
-
403
- const toolEvent = toolEvents[0] as ToolCallResultEvent;
404
- expect(toolEvent.messageId).toBe("tool-msg-1");
405
- expect(toolEvent.toolCallId).toBe("tool-call-123");
406
- expect(toolEvent.content).toBe("Tool execution result");
407
- expect(toolEvent.role).toBe("tool");
408
- });
409
- });
410
-
411
- describe("Run Isolation", () => {
412
- it("should store each run's events separately", async () => {
413
- const threadId = "test-thread-isolation";
414
-
415
- // First run
416
- const agent1 = new TestAgent([
417
- {
418
- type: EventType.TEXT_MESSAGE_START,
419
- messageId: "run1-msg",
420
- role: "assistant",
421
- } as TextMessageStartEvent,
422
- {
423
- type: EventType.TEXT_MESSAGE_CONTENT,
424
- messageId: "run1-msg",
425
- delta: "From run 1",
426
- } as TextMessageContentEvent,
427
- {
428
- type: EventType.TEXT_MESSAGE_END,
429
- messageId: "run1-msg",
430
- } as TextMessageEndEvent,
431
- ]);
432
-
433
- await firstValueFrom(
434
- runner.run({
435
- threadId,
436
- agent: agent1,
437
- input: { messages: [], state: {}, threadId, runId: "run-1" },
438
- }).pipe(toArray())
439
- );
440
-
441
- // Second run
442
- const agent2 = new TestAgent([
443
- {
444
- type: EventType.TEXT_MESSAGE_START,
445
- messageId: "run2-msg",
446
- role: "assistant",
447
- } as TextMessageStartEvent,
448
- {
449
- type: EventType.TEXT_MESSAGE_CONTENT,
450
- messageId: "run2-msg",
451
- delta: "From run 2",
452
- } as TextMessageContentEvent,
453
- {
454
- type: EventType.TEXT_MESSAGE_END,
455
- messageId: "run2-msg",
456
- } as TextMessageEndEvent,
457
- ]);
458
-
459
- await firstValueFrom(
460
- runner.run({
461
- threadId,
462
- agent: agent2,
463
- input: { messages: [], state: {}, threadId, runId: "run-2" },
464
- }).pipe(toArray())
465
- );
466
-
467
- // Connect and verify both runs' events are present
468
- const storedEvents = await firstValueFrom(
469
- runner.connect({ threadId }).pipe(toArray())
470
- );
471
-
472
- const messageIds = new Set<string>();
473
- for (const event of storedEvents) {
474
- if ('messageId' in event && event.messageId) {
475
- messageIds.add(event.messageId);
476
- }
477
- }
478
-
479
- expect(messageIds.has("run1-msg")).toBe(true);
480
- expect(messageIds.has("run2-msg")).toBe(true);
481
- });
482
- });
483
- });