@@ -10,99 +10,45 @@ import type { StoredChat, StoredMessage } from "./types";
1010import type { Client } from "../agent/client" ;
1111
1212// Helper to create a mock agent
13- function createMockAgent (
14- responseText : string = "Assistant response"
15- ) : Client & { chatCalls : any [ ] } {
13+ function createMockAgent ( responseText : string = "Assistant response" ) : {
14+ lock : RWLock ;
15+ client : Client ;
16+ chatCalls : any [ ] ;
17+ } {
1618 const chatCalls : any [ ] = [ ] ;
1719 return {
18- agentLock : new RWLock ( ) ,
20+ lock : new RWLock ( ) ,
1921 chatCalls,
20- chat : async ( { messages, signal } : any ) => {
21- chatCalls . push ( { messages, signal } ) ;
22+ client : {
23+ chat : async ( { messages, signal } : any ) => {
24+ chatCalls . push ( { messages, signal } ) ;
2225
23- // Return a ReadableStream of UIMessageChunk objects
24- const stream = new ReadableStream < UIMessageChunk > ( {
25- async start ( controller ) {
26- if ( signal ?. aborted ) {
27- controller . close ( ) ;
28- return ;
29- }
30-
31- // Start the message
32- controller . enqueue ( {
33- type : "start" ,
34- messageId : "msg-1" ,
35- } as UIMessageChunk ) ;
36-
37- // Add text content
38- controller . enqueue ( {
39- type : "text-start" ,
40- id : "text-1" ,
41- } as UIMessageChunk ) ;
42-
43- // Send text
44- controller . enqueue ( {
45- type : "text-delta" ,
46- id : "text-1" ,
47- delta : responseText ,
48- } as UIMessageChunk ) ;
49-
50- if ( ! signal ?. aborted ) {
51- controller . enqueue ( {
52- type : "text-end" ,
53- id : "text-1" ,
54- } as UIMessageChunk ) ;
55-
56- controller . enqueue ( {
57- type : "finish" ,
58- finishReason : "stop" ,
59- usage : { promptTokens : 10 , completionTokens : 5 } ,
60- } as UIMessageChunk ) ;
61- }
62- controller . close ( ) ;
63- } ,
64- } ) ;
65-
66- return stream ;
67- } ,
68- } as any ;
69- }
70-
71- // Helper to create a slow-streaming agent (yields control between chunks)
72- function createSlowAgent ( chunks : number = 5 ) : Client {
73- return {
74- agentLock : new RWLock ( ) ,
75- chat : async ( { signal } : any ) => {
76- const stream = new ReadableStream < UIMessageChunk > ( {
77- async start ( controller ) {
78- try {
26+ // Return a ReadableStream of UIMessageChunk objects
27+ const stream = new ReadableStream < UIMessageChunk > ( {
28+ async start ( controller ) {
7929 if ( signal ?. aborted ) {
8030 controller . close ( ) ;
8131 return ;
8232 }
8333
34+ // Start the message
8435 controller . enqueue ( {
8536 type : "start" ,
8637 messageId : "msg-1" ,
8738 } as UIMessageChunk ) ;
8839
40+ // Add text content
8941 controller . enqueue ( {
9042 type : "text-start" ,
9143 id : "text-1" ,
9244 } as UIMessageChunk ) ;
9345
94- for ( let i = 0 ; i < chunks ; i ++ ) {
95- if ( signal ?. aborted ) {
96- throw new Error ( "AbortError" ) ;
97- }
98- controller . enqueue ( {
99- type : "text-delta" ,
100- id : "text-1" ,
101- delta : `chunk${ i } ` ,
102- } as UIMessageChunk ) ;
103- // Yield control to allow other operations
104- await new Promise ( ( resolve ) => setImmediate ( resolve ) ) ;
105- }
46+ // Send text
47+ controller . enqueue ( {
48+ type : "text-delta" ,
49+ id : "text-1" ,
50+ delta : responseText ,
51+ } as UIMessageChunk ) ;
10652
10753 if ( ! signal ?. aborted ) {
10854 controller . enqueue ( {
@@ -117,18 +63,78 @@ function createSlowAgent(chunks: number = 5): Client {
11763 } as UIMessageChunk ) ;
11864 }
11965 controller . close ( ) ;
120- } catch ( err : any ) {
121- if ( err . message === "AbortError" || signal ?. aborted ) {
66+ } ,
67+ } ) ;
68+
69+ return stream ;
70+ } ,
71+ } as any ,
72+ } ;
73+ }
74+
75+ // Helper to create a slow-streaming agent (yields control between chunks)
76+ function createSlowAgent ( chunks : number = 5 ) : { client : Client ; lock : RWLock } {
77+ return {
78+ lock : new RWLock ( ) ,
79+ client : {
80+ chat : async ( { signal } : any ) => {
81+ const stream = new ReadableStream < UIMessageChunk > ( {
82+ async start ( controller ) {
83+ try {
84+ if ( signal ?. aborted ) {
85+ controller . close ( ) ;
86+ return ;
87+ }
88+
89+ controller . enqueue ( {
90+ type : "start" ,
91+ messageId : "msg-1" ,
92+ } as UIMessageChunk ) ;
93+
94+ controller . enqueue ( {
95+ type : "text-start" ,
96+ id : "text-1" ,
97+ } as UIMessageChunk ) ;
98+
99+ for ( let i = 0 ; i < chunks ; i ++ ) {
100+ if ( signal ?. aborted ) {
101+ throw new Error ( "AbortError" ) ;
102+ }
103+ controller . enqueue ( {
104+ type : "text-delta" ,
105+ id : "text-1" ,
106+ delta : `chunk${ i } ` ,
107+ } as UIMessageChunk ) ;
108+ // Yield control to allow other operations
109+ await new Promise ( ( resolve ) => setImmediate ( resolve ) ) ;
110+ }
111+
112+ if ( ! signal ?. aborted ) {
113+ controller . enqueue ( {
114+ type : "text-end" ,
115+ id : "text-1" ,
116+ } as UIMessageChunk ) ;
117+
118+ controller . enqueue ( {
119+ type : "finish" ,
120+ finishReason : "stop" ,
121+ usage : { promptTokens : 10 , completionTokens : 5 } ,
122+ } as UIMessageChunk ) ;
123+ }
122124 controller . close ( ) ;
123- } else {
124- controller . error ( err ) ;
125+ } catch ( err : any ) {
126+ if ( err . message === "AbortError" || signal ?. aborted ) {
127+ controller . close ( ) ;
128+ } else {
129+ controller . error ( err ) ;
130+ }
125131 }
126- }
127- } ,
128- } ) ;
129- return stream ;
130- } ,
131- } as any ;
132+ } ,
133+ } ) ;
134+ return stream ;
135+ } ,
136+ } as any ,
137+ } ;
132138}
133139
134140// Helper to create a stored message
0 commit comments